1

私はOracleを初めて使用し、頻繁に使用される2つの機能を持っています。そして、私はそれらの間でどちらが優れているのだろうか.

これです:

FUNCTION GET_MY_MONEY (myType IN NUMBER) RETURN NUMBER AS
    var_amount   NUMBER;
    var_result   NUMBER;
BEGIN
    var_result := 0;
    var_amount := 0;
    SELECT amount INTO var_amount FROM mytable WHERE type = myType AND sysdate >= date_from AND sysdate <= date_to;
    var_result := var_amount*1000;
    RETURN var_result;
EXCEPTION
    WHEN OTHERS THEN
        RETURN 0;
END;

またはこれ:

FUNCTION GET_MY_MONEY (myType IN NUMBER) RETURN NUMBER AS
    var_count    NUMBER;
    var_amount   NUMBER;
    var_result   NUMBER;
BEGIN
    var_result := 0;
    var_count := 0;
    var_amount := 0;
    SELECT count(*) INTO var_count FROM mytable WHERE type = myType AND sysdate >= date_from AND sysdate <= date_to;
    IF (var_count > 0) THEN
        SELECT amount INTO var_amount FROM mytable WHERE type = myType AND sysdate >= date_from AND sysdate <= date_to;
        var_result := var_amount*1000;
        RETURN var_result;
    ELSE RETURN 0; END IF;
EXCEPTION
    WHEN OTHERS THEN
        RETURN 0;
END;

性能的にはどちらが良いですか?それらが呼び出されたとき、どちらがより速く戻りますか?

前もって感謝します。

4

3 に答える 3

4

一般的に、それは依存します。どのくらいの頻度で関数を呼び出し、myTypeクエリが 0 行を返す原因となる値を渡しますか?

呼び出しの 99.9% でクエリが 1 行だけを返す場合、2 番目のアプローチではクエリが 2 回実行されます。関心のあるブロックがキャッシュされることがほぼ保証されているため、2 番目の呼び出しによって関数が最初の呼び出しの 2 倍のコストになることはない可能性がありますが、2 番目のアプローチはほぼ確実に大幅に遅くなります。

一方、呼び出しの大部分にmyType行を返さない値が含まれる場合、2 番目の方法ではクエリを 2 回実行する必要がないことがよくあります。また、最初のアプローチでは、例外を処理する時間の大部分のオーバーヘッドが発生し、ほぼ確実に 2 番目のクエリよりもコストがかかります。

ほとんどの場合、より効率的なソリューションは、0 行が返される確率に基づいて明らかです。myTypeほとんどの場合、関数は、呼び出し元が渡される値が有効であるとかなり確信している場合にのみ呼び出されるため、最初のアプローチがより効率的になります。0 行が検出される呼び出しの割合が増加するにつれて、2 番目のアプローチがより効率的になります。その行がどこにあるかは、テーブル、データ、ハードウェア、Oracle のバージョンなど、多くの要因によって異なります。特定のコードの境界線が 10% か 20% か 90% かを判断するには、ベンチマーク テストを実行する必要があります。

于 2013-04-26T06:04:18.577 に答える