質問の対象となる RDBMS が特定されていないため、SQL Server でどのように動作するかを記述し、少し単純化し、多くの技術的な問題を回避しようとします。異なるシステムで同じまたは非常に類似している可能性がありますが、完全に異なる場合もあります。
クエリに対して SQL Server が行うこと
`SELECT name FROM users WHERE address IN (addr_a, addr_b, addr_c, ...);`
テーブルにあるインデックスの種類にほぼ完全に依存します。3 つの基本的なシナリオを次に示します。
シナリオ 1 (良いインデックス)
Covering Indexと呼ばれるものがある場合、これは列の PK またはクラスター化インデックス、またはincludeaddress
の非クラスター化インデックスのいずれかを意味し、SQL Server は と呼ばれるものを実行します。これは、インデックスのツリー構造を調べて、必要な正確な行をすばやく特定する (または存在しないことを検出する) ことを意味します。column も index に含まれているため、それを読み取り、そこからすぐに戻ります。address
name
Index Seek
name
シナリオ 2 (あまり良くないインデックス)
address
これは、 columnを含まないcolumn にインデックスがある場合ですname
。この種のインデックスは、1 つの列だけに頻繁に見られるかもしれませんが、すぐにわかるように、ほとんどの場合、ほとんど役に立たないことがわかります。ここで期待していることは、SQL Server がインデックス構造を調べて (シーク)、アドレスを含む行をすばやく見つけることです。ただし、列name
が現在存在しないため、行が実際にある行 ID (または PK) しか取得できないため、返された行ごとに別のインデックスまたはテーブルを追加で読み取り、行を見つけて名前を取得します。これにはシナリオ 1 の 3 倍の読み取り時間がかかるため、SQL Server は、インデックスを使用するよりもテーブルのすべての行を処理する方が安価であると判断しないことがよくあります。それはシナリオ 3 で説明されています。
シナリオ 3 (使用可能なインデックスがない)
これは、インデックスがまったくないか、列アドレスにインデックスがない場合に発生します。簡単に言えば、SQL Server はすべての行を調べて、すべての行で条件をチェックします。これが呼び出されますIndex Scan
(またはTable Scan
インデックスがまったくない場合)。通常、最悪のシナリオであり、まったく低速です。
物事を少し明確にするのに役立つことを願っています。
長い文字列の速度低下に関する他のサブ質問については、この場合の答えは「おそらくあまりない」でしょう。SQl Server が 2 つの文字列を比較する場合、文字単位で比較されるため、両方の文字列の最初の文字が異なる場合、それ以上のチェックは行われません。ただし、文字列の先頭にワイルドカード % を配置すると、つまり、WHERE address LIKE '%addr_a'
SQL Server は列内のすべての文字列のすべての文字をチェックする必要があるため、動作が大幅に遅くなります。