ORA-01795: リストに指定できる式の最大数は1000です。

引き続きソース読み。IN句の要素にSELECT文を使っているSQLを発見。こんな感じ

SELECT *
FROM FOO
WHERE FOO.ID IN ( SELECT BAR.ID FROM BAR )

見つけた箇所の()内は要素数が1000を超える可能性があるからIN句は使っちゃダメなはず。しかもこのSQLはエラーハンドリングがまともにされていないというオマケ付きw。ふつーはこう書くだろう。

SELECT FOO.*
FROM FOO, BAR
WHERE FOO.ID = BAR.ID

それはIN句を書いた人も当然わかっていたと思う。でもできなかった。これはDAOっぽいクラスの中の処理のお話。FROMに指定できるテーブルは1個だけ。だからIN句で逃げた。でも、どうせ逃げるならEXISTS句使えばいいのにね。最初の例は次のように書き換えられると思う。

SELECT *
FROM FOO
WHERE EXISTS ( SELECT 1 FROM BAR WHERE FOO.ID = BAR.ID )

IN句の要素数の上限は昔から1000だった気がする。もしかしたらOracle7の頃からずっと変わっていないかも。多分それは、パフォーマンスに影響するからだと思う。実際にどういった実行計画になるかはOracle任せだから、どっちが速いとは一概にいえない。ただIN句には要素数の限界があるから、この場面では使うべきじゃなかった。まぁ典型的なやっつけ仕事ですねw。