4

ストアド プロシージャ (「paramDate」という名前の日付パラメーターを持つ) では、このようなクエリがあります

select id, name
from customer
where period_aded = to_char(paramDate,'mm/yyyy')

Oracle は行ごとに paramDate を文字列に変換しますか?

オラクルはそうしないと確信していましたが、オラクルはそうすると言われました。実際、関数のパラメーターが制約である場合 (クエリ内でフィールドも計算値も取得されていない場合)、結果は常に同じになるはずであり、そのため、Oracle はこの変換を 1 回だけ実行する必要があると考えました。その後、いくつかの関数で DML 文を実行したことがあることに気付きました。これにより、行ごとに変化しない場合でも、結果の値が変化する可能性があります。

これは、そのような値をクエリに追加する前に変換する必要があることを意味するはずです。

とにかく、おそらくよく知られている「既知の関数」(組み込み)は一度評価されるか、私の関数でさえ評価されます。

とにかく、また…

Oracleはそのto_charを1回実行しますか、それとも行ごとに実行しますか?

回答ありがとうございます

4

3 に答える 3

8

インデックスが使用できなくなるため、これは一般的には当てはまらないと思います。

少なくとも組み込み関数の場合、Oracle はそれを 1 回しか評価できないことを認識できるはずです。(ユーザー定義関数については、以下を参照してください)。

以下は、インデックスが使用されているケースです (関数はすべての行に対して評価されません)。

SQL> select id from tbl_table where id > to_char(sysdate, 'YYYY');

--------------------------------------------------------------------------------
| Id  | Operation        | Name        | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |             |    35 |   140 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| SYS_C004274 |    35 |   140 |     1   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

1 - access("ID">TO_NUMBER(TO_CHAR(SYSDATE@!,'YYYY')))

ユーザー定義関数については、この記事をご覧ください。関数が 1 回だけ呼び出されるようにする 2 つの方法について説明します。

  1. Oracle 10.2 以降、関数を DETERMINISTIC として定義できます。

  2. 古いバージョンでは、「スカラー サブクエリ キャッシュ」を使用するように言い換えることができます。

    SELECT COUNT(*) FROM EMPLOYEES WHERE SALARY = (SELECT getValue(1) FROM DUAL);

于 2009-07-13T01:31:21.630 に答える
1

DETERMINISTICキーワード(ここに1つここにもう1つ)の記述を見ると、関数が同じ入力パラメーターに対して同じ値を返すことを開発者がOracleに通知できるようにするために導入されました。したがって、関数を1回だけ呼び出す必要があり、同じ入力パラメーターに対して常に同じ値を返すことを保証できる場合は、キーワードDETERMINISTICを使用できます。

のような組み込み関数に関してはto_char、オラクルの内部に精通している人に指示を与えることをお勧めします。

于 2009-07-13T01:45:28.603 に答える
1

to_char に関する懸念は、私にはわかりません。ただし、pl/sql では、

create or replace procedure ........
  some_variable varchar2(128);
begin

  some_variable := to_char(paramDate,'mm/yyyy');

  -- and your query could read

  select id, name from customer where period_aded = some_variable;
.
.
.
end;
/

Kt

于 2009-07-13T01:09:12.013 に答える