20

テーブルTの列A、B、C、Dにインデックスがあります

WHERE 句で A、B、C を使用して T から取得するクエリがあります。

索引は使用されますか、それとも A、B、C のみを含む別の索引が必要ですか?

4

8 に答える 8

15

実行計画をチェックして、インデックスが使用されていることを確認する必要があるという David B の意見は正しいです。

索引は使用されますか、それとも A、B、C のみを含む別の索引が必要ですか?

質問のこの最後の部分に答えるために、(当面の解決策とは対照的に) 基本的なトピックの核心だと思いますが、インデックス付きの列のサブセットにインデックスを付ける理由はほとんどありません。インデックスが (A, B, C, D) の場合、(A, B, C) に対する WHERE は、理想的な状況である index seekになる可能性が最も高くなります。インデックスには、エンジンが必要とするすべての情報が含まれています。結果セットに直接移動します。これは、数値型と文字列型の等価性テストに当てはまると思いますが、LIKE '%'s) で壊れる可能性があります。一方、WHERE が D のみを参照している場合は、インデックススキャンで終わる可能性が最も高いでしょう。これは、SQL エンジンが A、B、および C のすべての組み合わせをスキャンし、D が条件を満たしているかどうかを確認してから、行を結果セットに追加するかどうかを決定する必要があることを意味します。特に大きなテーブルで、列「D」に対して多くのクエリを実行する必要があることに気付いたとき、D のみにインデックスを追加したところ、パフォーマンスが約 90% 向上しました。

編集: SQL Management Studio でデータベース エンジン チューニング アドバイザを使用することもお勧めします。実行するクエリに対してテーブルが理想的にインデックス化されていないかどうかがわかります。

于 2008-09-25T20:11:25.327 に答える
8

場合によります!

WHERE A like '%x%'
  and B = 1
  and C = 1
//
WHERE A = 1
  OR B = 1
  OR C = 1
//
WHERE DateAdd(dd, 1, A) = '2008-01-01'
  AND B = 1
  AND C = 1

インデックスは役に立たないため、これらはインデックスに依存しません。

「推定実行プランの表示」をクリックして、潜在的なインデックスの使用を確認します。

于 2008-09-25T19:49:20.920 に答える
5

Oracleデータベースでは、これは複合インデックスと呼ばれます(12gドキュメントですが、以前のバージョンで有効です)

複合インデックスは、WHERE句が複合インデックスの列の先頭部分すべてを参照するSELECTステートメントのデータの取得を高速化できます。したがって、定義で使用される列の順序は重要です。一般に、最も一般的にアクセスされる列が最初に配置されます。

あなたの場合はそうです インデックスが使用される/使用される可能性があります。これは、ExplainPlanを使用して確認できます。

MS SQLSERVERが異なる場合(そしておそらくそうかもしれませんが)、新しい答えが必要になります。

編集:それは使用するためのインデックスのみを考慮する ことにも言及する必要があります..それは必ずしもそれがそれを使用することを意味するわけではありません。

Edit2: Oracle 11g以降には、インデックスの列をスキップできるオプションが追加されました。したがって、A、B、およびDのクエリは引き続きインデックスを使用する可能性があります

于 2008-09-25T19:45:54.127 に答える
4

はい、インデックスが使用されます。どのインデックスがより最適なクエリプランを生成するかについてはかなり賢明であり、問​​題はないはずです。

この種のことと同じように、私の言葉を信じないでください-ベンチマークしてください。テーブルを作成し、代表的なデータを入力し、クエリを実行し、インデックスを作成して、もう一度クエリを実行します。

于 2008-09-25T19:49:24.727 に答える
2

単純な等しいルックアップ(WHERE A=1およびB='Red'およびC=287)から始めます。はい、インデックスが(ほとんどの場合)使用されます。インデックスは、オプティマイザが選択に一致する行数を「推測」するために最初に使用され、次にそれらの行に実際にアクセスするために使用されます。

「like」述語に関するDavidBのコメントに応えて、SQLServerは引き続きインデックスを使用する場合があります。これは、選択しているものによって異なります。たとえば、count(*)を選択している場合、SQLServerはインデックスをスキャンし、where句に一致するヒットをカウントする可能性があります。これは、インデックスが小さく、スキャンに必要なIOが少ないためです。また、SQLServerがインデックスをどの程度選択していると感じるかに応じて、ベーステーブルからいくつかの列を選択している場合でも、それを行うことを決定する場合があります。

于 2008-09-25T19:57:16.237 に答える
2

クエリで使用されていない列がインデックスに含まれているという事実は、その列の使用を妨げるものではありません。

必ず使用されるというわけはありませんが、別の理由で無視される場合があります (おそらく、1 つ以上の他のインデックスの方が便利なためです)。

いつものように、推定実行計画で何が起こる可能性があるかを見てみましょう。

于 2008-09-25T19:56:31.200 に答える
1

一般的に言って、そうなるでしょう、すべての現代のデータベースはこれを行うのに十分賢いです。例外があります。たとえば、テーブルの統計で、テーブル内のデータの量が十分に少なく、テーブル全体の読み取りがより効率的であることが示されている場合、インデックスは割り引かれますが、原則として、それに依存することができます。適切な場において。

したがって、インデックスを設計するときにこれを利用できます。たとえば、キー値としてA、B、Cを含むテーブルと、ステートメントによって頻繁に取得されることがわかっているデータを含む列YおよびZがあるとします。

SELECT Y FROM table WHERE A = alpha and B = beta and C = gamma 

SELECT Z FROM table WHERE A = alpha and B = beta and C = gamma 

私は通常、A、B、C、X、Zにインデックスを作成します-XとZが適度に小さいフィールドであると仮定します。この理由は、上記のステートメントのアクセス経路がインデックスを使用することを知っているためです。取得するデータはすでにインデックス読み取りに含まれているため、テーブルデータ自体を取得するためにデータブロックを個別に読み取る必要はありません。必要になります。この戦略により、状況によってはデータの取得を劇的に高速化できます。もちろん、更新コストとディスク容量で支払うため、適用する前にデータベースの動作を理解する必要がありますが、ほとんどのデータベースの読み取り数は書き込み数を大幅に上回っているため、一般的に検討する価値があります。

于 2008-09-25T20:06:22.750 に答える
1

ここに別の「依存する」答えがあります...それはまた、テーブルの大きさにも依存します...

実行計画をチェックして、インデックスが使用されているかどうかを確認することに言及した他のすべての人に同意します。

以下に、実行計画の読み方に関する役立つ記事をいくつか示します。

http://www.sqlservercentral.com/articles/A Managing/executionplans/1345/ http://www.codeproject.com/KB/database/sql-tuning-tutorial-1.aspx

私がお勧めするシークとスキャンに関する良い記事もあります: http://blogs.msdn.com/craigfr/archive/2006/06/26/647852.aspx

Craig Freedman のブログには優れた記事のログがあります。役に立つ記事をもう 1 つ紹介します。この記事では、使用するインデックスを決定するために SQL Server が使用するいくつかの要因について説明します...

http://blogs.msdn.com/craigfr/archive/2006/07/13/664902.aspx

気をつけて!ジェフ

于 2008-09-25T21:15:43.020 に答える