演算子DETERMINISTIC
の右側で関数を使用すると、Oracle の実行計画が大混乱を引き起こします。LIKE
これは私の状況です:
状況
次のようなクエリを実行するのが賢明だと思いました(簡略化):
SELECT [...]
FROM customers cust
JOIN addresses addr ON addr.cust_id = cust.id
WHERE special_char_filter(cust.surname) like special_char_filter(?)
?
そして、私はのようなものにバインドします'Eder%'
。現在customers
、addresses
非常に大きなテーブルです。そのため、インデックスを使用することが重要です。もちろん、通常のインデックスがありaddresses.cust_id
ます。しかし、関数ベースのインデックスも作成しましたspecial_char_filter(customers.surname)
。これは非常にうまく機能します。
トラブル
問題は、like
句を含む上記のクエリが FULL TABLE SCANS on で実行プランを作成することaddresses
です。このクエリの何かが、Oracle が でインデックスを使用できないようにしているようですaddresses.cust_id
。
回避策
私の問題の解決策は次のとおりであることがわかりました。
SELECT [...]
FROM customers cust
JOIN addresses addr ON addr.cust_id = cust.id
WHERE special_char_filter(cust.surname) like ?
DETERMINISTIC
like 演算子の右側から( !) 関数を削除し、バインド変数を Java で事前に計算しました。現在、このクエリは超高速で、FULL TABLE SCANS はありません。これも非常に高速です (同等ではありませんが)。
SELECT [...]
FROM customers cust
JOIN addresses addr ON addr.cust_id = cust.id
WHERE special_char_filter(cust.surname) = special_char_filter(?)
混乱
私はこれを理解していません。like
演算子の右側に決定論的関数があることの何が問題になっていますか? 私はこれをOracle 11.2.0.1.0で観察しました