4

ORACLEデータベースで最速のものは何ですか?

selectステートメント内で関数を呼び出して、各行の単一の値を取得します

SELECT field1, field2, F_GET_LIBELLE_STATUT( field2 ) FROM table1 WHERE ...

単純な関数で:

create or replace
FUNCTION "F_GET_LIBELLE_STATUT" (v_statut NUMBER) RETURN VARCHAR2 IS
tmpVar VARCHAR2(40);
BEGIN
   select libelle into tmpVar from t_statut_ope where id_statut = v_statut;
   RETURN tmpVar;
   EXCEPTION
     WHEN NO_DATA_FOUND THEN
       RETURN '';
     WHEN OTHERS THEN
       -- Consider logging the error and then re-raise
       RAISE;
END f_get_libelle_statut;

または、selectステートメントで結合を実行しますか?

Select a.field1, a.field2, b.libelle
FROM table1 a LEFT JOIN t_statut_ope b ON b.id_statut = a.field2
WHERE ...

そして、selectと節の条件で多くの関数(10個以上)を呼び出した場合も同じ答えですか?

ご回答有難うございます。

4

4 に答える 4

9

SQL で実行できることはすべて SQL (*)で実行する必要があります。

セットベースの操作は、行をアゴナイズすることにより常に行よりも高速であるため、結合はその関数を呼び出すよりも常に高速です。次に、SQL と PL/SQL の間を移動するオーバーヘッドがあります。さらに、これらの NO_DATA_FOUND 例外を処理するオーバーヘッドが発生します。これは、ギャップが予期され、許容されるため、真の例外ではありません。最後に、オプティマイザは、必要なすべての情報を提供したため、純粋な SQL オプションのより良い計画を選択します。


(*)私はこの質問に答えたとき、与えられた例に焦点を当てて答えました。私はその答えを支持します. テーブルに対して SQL を使用して (結合、ビュー、インライン ビュー、サブクエリを介して) 必要なデータを取得できる場合は、それを行う必要があります。しかし、根底にある質問に掘り下げたいと思います。なぜオラクルはクエリでの関数の使用をサポートしているのでしょうか? SQL ではできないことを行う必要がある場合があるからです。

table()結合(またはインラインビュー、WITH句などの他のSQL構造)を使用する代わりに、SQLを実行する関数を呼び出すためのユースケースを次に示します(私は主に呼び出しによって呼び出される関数を考えています):

  1. クエリは動的です。動的 SQL には PL/SQL が必要なので、ここでは関数は彼だけです。
  2. 行の生成。PL/SQL を使用して、入力を複数の文字列に分割する (CSV トークン化など) か、テーブルからではなくデータを生成する可能性があります。場合によってはまだ有効ですが、正規表現のサポートと気の利いた CONNECT BY LEVEL <= N トリックにより、より一般的な使用法がビン化されました。
  3. データは PL/SQL API の背後にカプセル化されるため、呼び出すことができるのは関数だけです。
  4. 奇妙な理由により、PL/SQL を使用してフィルタまたはルックアップを実装することによってのみ、必要なパフォーマンスを得ることができます。どうやら。正直なところ、私はこれをしなければならなかったケースを思い出すことはできません (ただし、パイプライン化された関数をサブクエリまたはインライン ビューに変換するとパフォーマンスが向上したケースがいくつかありました)。ひょっとしたら隠居生活を送ってきたのかもしれません。確かに、反例のベンチマーク引用を歓迎します。
于 2012-05-03T09:32:28.013 に答える
2

関数メソッドが最適な状況はごく少数であり、デフォルトでは使用しません。結合はデータベースが行うように設計されているため、最初の選択肢として使用する必要があります。

于 2012-05-03T09:42:08.890 に答える
1

これら 2 つの異なるクエリを使用して、自分で何を見つけましたか?

私の経験では、結合は関数よりも 10 倍中 9 倍高速です。少なくとも、関数で別のクエリ/テーブル/ビューにアクセスしている場合。関数は実行ごとに評価する必要があります。結合はおそらくより大きなデータセットを生成しますが、テーブルを (キーで) 結合するだけでよく、かなり高速です。

于 2012-05-03T06:59:40.910 に答える
0

または、外部結合を忘れて、変換を行う選択ステートメントを選択リストに入れます [これは、外部結合よりも高速な場合があります]:

SELECT field1, field2
, (select libelle from t_statut_ope b where b.id_statut = a.field2) libelle
FROM table1 a
WHERE 1=1
;
于 2012-05-03T14:48:14.883 に答える