はじめに
シンプルで直感的に書ける SQL ですが、書き方に注意しないと、インデックスを使った方が効率的にも関わらずインデックスを使わない実行計画になってしまうといった SQLアンチパターンが存在します。
例えば、「顧客を管理しているテーブルから与信限度の2倍が 40,000 より大きい顧客の顧客IDを抽出する SQL」を自然体で記述すると下記のようになると思います。
SELECT cust_id FROM select_ai_user.customers WHERE cust_credit_limit * 2 > 40000;
しかし、この SQL では下記の通りインデックスが使用されません。cust_credit_limitのインデックスはcust_credit_limitを2倍した値を持っていない為です。

対処の一例として、WHERE句の算術演算子を左辺に記述せず、右辺に記述します。
SELECT cust_id FROM select_ai_user.customers WHERE cust_credit_limit > 40000 / 2;
実行計画が変化し、CUST_IND_CREDITが使用されるようになったことがわかります。

自然言語をもとに SQL を生成してくれるオラクルの Select AI が、こういった SQLアンチパターンを考慮してくれるのか試してみます。
Select AI を使うにあたっては下記を参考にしました。
ただし、データセットの準備 (2-2-5) がうまくいかなかったため、ADB にあらかじめ用意されている SHスキーマをサンプルとして使用しました。
Select AI 自体については下記のP16が参考になるかと思います。
やってTRY
文章の前にshowsqlを付けることで、Select AI で生成される SQL を確認することができます。
残念ながら、SQLアンチパターンを考慮した SQL にはなりませんでした。

文章を直せば期待の SQL になりますが、通常このような文章はあまり書かないかと思います。

念のため生成された SQL の実行計画を確認しましたが、冒頭で記載した通りの実行計画となりました。

無理やり文章に「インデックスを使用して抽出」等書くとどうなるか試してみましたが、いずれも余計な条件や関数が付いてしまいました。

生成される SQL に揺らぎがある可能性を考えると、SQLパッチで SQL や SQLID をキーに実行計画をコントロールすることも難しいと考えられ、対処法としは今の所cust_credit_limit * 2のインデックスを作成するぐらいしか思いつきません…(性能問題になる場合は、ですが)
Select AI の今後のレベルアップに期待です ![]()
余談
今回の検証だけで、OCI利用料が普段の月額利用料の数倍になってしまいました ![]()
![]()
Select AI が高いのか??と思いきや、その分は OCI Generative AI として計上されてるようで微々たるものですし、大した処理も投げていないので謎です…![]()
解明できれば共有しようと思います…


