10

SQLSELECTステートメントでは、そのステートメントのスコープに対して決定論的な関数を実行したいと思いますSELECT(またはトランザクションも問題ありません)。

select t.x, t.y, my_function(t.x) from t

の多くの値はt.x同じであるため、Oracle は同じ関数を何度も呼び出すことを省略して、処理を高速化できます。しかし、関数に というラベルを付けるとDETERMINISTIC、このクエリを数回実行する間に結果がキャッシュされる可能性があります。使用できない理由は、時々変更される構成パラメーターを使用するDETERMINISTICためです。my_function

他に使用できるキーワードはありますか?注意すべき点はありますか (メモリの問題、同時実行性など)? あるいは、t.x値ごとに 1 回だけ関数を呼び出す分析関数などの他のトリック (パフォーマンスに大きな影響を与えずに) はありますか?

4

4 に答える 4

11

これを行う場合:

select t.x, t.y, (select my_function(t.x) from dual)
from t

その後、Oracle はサブクエリ キャッシングを使用して関数呼び出しを削減できます。

于 2011-09-01T13:20:32.413 に答える
3

これはあなたの質問に対する答えではありませんが、解決策になる可能性があります。あなたが言及したこの構成パラメーターは、機能するパラメーターとして追加できませんか? この場合、my_function(t.x, val1)は とは別のものですmy_function(t.x, val2)

于 2011-09-01T13:09:06.180 に答える
2

考えられる単純な回避策は、最初の関数を呼び出す2番目のDETERMINISTIC関数を作成することです。ただし、2番目の関数に、関数を使用するクエリごとに異なるリテラル値を指定する、意味のない追加のパラメーターを取得させます。

于 2011-09-01T13:07:22.967 に答える
2

もう 1 つの方法は、関数をパッケージに入れて、結果をグローバル変数として設定することです。次に、関数を呼び出すときに、入力変数が以前と同じであるかどうかを確認し、そうである場合はすぐにグローバル変数を返します。

SQL> create or replace package temp is
  2
  3    function blah ( PIndex integer ) return integer;
  4
  5  end temp;
  6  /

Package created.

SQL>
SQL> create or replace package body temp is
  2
  3    GResult integer := 0;
  4    GIndex integer;
  5
  6    function blah ( PIndex integer ) return integer is
  7
  8      begin
  9
 10        if Gindex = Pindex then
 11          return Gresult;
 12        else
 13          GIndex := Pindex;
 14          GResult := Pindex;
 15        end if;
 16
 17        return Gresult;
 18
 19      end blah;
 20
 21  end temp;
 22  /

Package body created.

SQL>
SQL> select temp.blah(1) from dual;

TEMP.BLAH(1)
------------
           1

SQL>
SQL> select temp.blah(1) from dual;

TEMP.BLAH(1)
------------
           1

SQL>
SQL> select temp.blah(2) from dual;

TEMP.BLAH(2)
------------
           2

SQL>
于 2011-09-01T13:32:17.697 に答える