演算子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 ?
DETERMINISTIClike 演算子の右側から( !) 関数を削除し、バインド変数を 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で観察しました