次のようなクエリがあります。
select
id
, int1
, int2
, (select count(*) from big_table_with_millions_of_rows
where id between t.int1 and t.int2)
from myTable t
where
....
この選択では、正確に 1 行が返されます。インライン選択で使用される ID は、インデックス付きの列 (主キー) です。andをこの 1 つの行から返された int1/int2 の値に置き換えるt.int1
と、クエリはミリ秒で完了します。t.int2
上記のクエリを実行すると、つまり int1/int2 への参照を使用すると、約 10 分かかります。プロファイラーを実行して実際に何が起こっているかを確認すると、99% の時間、エンジンがインライン クエリからデータを返すためにビジーであることがわかります。MySql が実際に実行されているように見えます。
select ... from big_table_with_millions_of_rows
を適用する前に、インライン クエリのビットを 1 回
where id between t.int1 and t.int2
結果にビット。これは本当ですか?そうでない場合、何が起こっているのですか?SELECT
inlineは、クエリの最後の要素として行ごとに実行されるため、潜在的に危険であると常に考えていましたが、このような状況では、イニシャルSELECT
が非常に選択的であり、非常に効率的です。誰でもこれに光を当てることができますか?
編集:これまでのフィードバックに感謝します。私の懸念は、インラインクエリの行ごとの性質についてではなく、(同じ) ハードコーディングされた値ではなく、変数に直面したときに主キーインデックスを使用できないように見えるという事実です。私の推測では、ANALYZE が最近実行されていない場合、オプティマイザは、データ分散に関する知識がないため、テーブル スキャンを実行する必要があると想定します。しかし、範囲検索が主キーで行われるという事実は、それを補うものではないでしょうか?