私は面白い面接を最近行ったことがあります。そこでは、スカラーの長いリスト(何千もの値)を含むWHERE..IN
句を使用してクエリを最適化することについての質問がありました。この質問は、IN
句のサブクエリに関するものではなく、スカラの簡単なリストについてです。最適化:WHERE x IN(1,2、.. 100.000)とINNER JOIN tmp_table USING(x)?
これは、INNER JOIN
を使って、スカラーだけを含む別のテーブル(おそらく一時的なもの)を使って最適化できるとすぐ答えました。私の答えは受け入れられ、査読者から「データベースエンジンは現時点では実行可能な状態で十分に長い時間を最適化することはできません」というメモがありました。私はうなずきました。
しかし、私が歩いて行ったとき、私は疑問を持ち始めました。この状態は、現代のRDBMSにとっては、それを最適化することができないほどには些細で広く使われていたようです。だから、私はいくつかの掘り出しを開始しました。
のPostgreSQL:
それはsortedあるPostgreSQLのparse scalar IN()
constructions into ScalarArrayOpExpr
structure、こと、らしいです。この構造体は後でインデックススキャン中に一致する行の位置を特定するために使用されます。このようなクエリの場合、EXPLAIN ANALYZE
は1つのループしか表示しません。結合は行われません。だから、私はそのようなクエリがINNER JOINよりも速くなると期待しています。私は既存のデータベースでいくつかのクエリを試してみました。しかし、私はテストの純度を気にせず、Postgresはバグダントの下にあったので間違っているかもしれません。
MSSQLサーバー:
MSSQLサーバーbuilds a hash structure from the list of constant expressions and then does a hash join with the source table。並べ替えが行われていないようだが、それはパフォーマンスマッチだと私は思う。このRDBMSの経験がないので、私はテストをしませんでした。
MySQLサーバ:
The 13th of these slidesは5.0前に、この問題は確かにいくつかのケースでMySQLで起こったことを、述べています。しかし、それ以外には、私は悪いIN()
治療に関連する他の問題は見つかりませんでした。私は残念ながら逆の証拠を見いだせませんでした。あなたがしたら、私を蹴ってください。
のSQLite:
Documentation pageは、いくつかの問題をヒントが、私は物事は概念レベルで実際にそこにある説明と信じる傾向にあります。その他の情報は見つかりませんでした。
私はインタビュアーを誤解したり、Googleを誤用していると思っています;それは、条件を設定していないし、話が少し曖昧になったからですRDBMSまたは他の条件。それはちょうど抽象的な話だった)。
それはずっと前にあるデータベースが(ところで、リストにNULL
値で時々問題を引き起こす可能性があります)OR
文のセットとしてIN()
を書き直した日、のように見えます。か否か?
もちろん、スカラーのリストが許可されたデータベースプロトコルパケットよりも長い場合は、INNER JOIN
しか利用できない可能性があります。
私はいくつかのケースでは、(それが準備されていない場合)だけでパフォーマンスを殺すことができるクエリの解析時間だと思う。
また、データベースでは、何度も何度も再解析を行うようになるIN(?)
クエリを準備できない可能性があります(パフォーマンスが低下する可能性があります)。実際には、私は試したことはありませんが、このような場合でもクエリの解析とプランニングはクエリの実行と比較して巨大ではないと思います。
しかし、それ以外の問題は他にはありません。まあ、この問題を抱えているだけの問題以外。内部に数千のIDを含むクエリがある場合、アーキテクチャに何か問題があります。
はあなたですか?
はINパラメータの大ammountsに問い合わせプランナのタイムアウトを取得しています。 –
興味深いですが、このサイトには適していません。あなたはそれを知っています...私は閉じようとしています。 –
私は[This thing](http://stackoverflow.com/a/34015333)に乱数と関連があったと書いています。私はそれをエンドツーエンドでやった。付録Cではリストで大きなものを使用しています。千要素。結果は2分の1秒です。 – Drew