質問
データベースの議論でカバードインデックスという用語を聞いたことがありますが、これはどういう意味ですか?
解決
あ カバーインデックス クエリに必要なすべての列、場合によってはそれ以上の列を含むインデックスです。
たとえば、これは次のとおりです。
SELECT *
FROM tablename
WHERE criteria
通常、インデックスを使用して、どの行を取得するかの解決を高速化します。 基準, 、しかし、その後、行を取得するためにテーブル全体に移動します。
ただし、インデックスに列が含まれている場合は、 列1、列2 そして 列3, 、次にこのSQL:
SELECT column1, column2
FROM tablename
WHERE criteria
また、特定のインデックスを使用して取得する行の解決を高速化できる場合、そのインデックスには関心のある列の値がすでに含まれているため、行を取得するためにテーブルに移動する必要はありません。ですが、インデックスから直接結果を生成することもできます。
これは、一般的なクエリが行を解決するために 1 ~ 2 列を使用し、通常はさらに 1 ~ 2 列を追加する場合にも使用できます。これらの追加の列を追加すると有益な場合があります (列がすべて同じである場合)。 ) をインデックスに追加することで、クエリ プロセッサがインデックス自体からすべてを取得できるようになります。
ここにあります 記事:インデックス カバリングにより SQL Server クエリのパフォーマンスが向上 件名に。
他のヒント
カバリングインデックスは普通のインデックスです。データを分析する必要がなくてもクエリを満たすことができる場合、それは「カバーリング」と呼ばれます。
例:
CREATE TABLE MyTable
(
ID INT IDENTITY PRIMARY KEY,
Foo INT
)
CREATE NONCLUSTERED INDEX index1 ON MyTable(ID, Foo)
SELECT ID, Foo FROM MyTable -- All requested data are covered by index
これは、SQL サーバーからデータを取得する最も速い方法の 1 つです。
カバーインデックスは、特定のテーブルに必要なすべての列を「カバー」するインデックスであり、特定のクエリ/操作で物理テーブルにアクセスする必要がまったくありません。
インデックスには目的の列 (またはそのスーパーセット) が含まれているため、テーブル アクセスをインデックス ルックアップまたはスキャンに置き換えることができます。一般に、この方がはるかに高速です。
取り上げるコラム:
- パラメータ化された条件または静的な条件。パラメータ化された条件または定数条件によって制限される列。
- 列を結合します。結合に動的に使用される列
- 選択された列。選択した値を回答します。
インデックスをカバーすると、多くの場合、検索に優れた利点が得られますが、挿入/更新のオーバーヘッドが若干増加します。これは、更新のたびに追加のインデックス行またはより大きなインデックス行を書き込む必要があるためです。
結合クエリのインデックスをカバーする
カバーインデックスは、結合クエリのパフォーマンス手法としておそらく最も価値があります。これは、結合クエリは単一テーブルの取得よりもコストが高く、コスト パフォーマンスの問題が発生する可能性が高いためです。
- 結合クエリでは、テーブルごとにインデックスをカバーすることを考慮する必要があります。
- 各「カバーインデックス」はプランから物理テーブルアクセスを削除し、インデックスのみのアクセスに置き換えます。
- 計画のコストを調査し、どのテーブルをカバーインデックスに置き換えるのが最も価値があるかを実験してください。
- これにより、大規模な結合計画の乗算コストを大幅に削減できます。
例えば:
select oi.title, c.name, c.address
from porderitem poi
join porder po on po.id = poi.fk_order
join customer c on c.id = po.fk_customer
where po.orderdate > ? and po.status = 'SHIPPING';
create index porder_custitem on porder (orderdate, id, status, fk_customer);
見る:
以下の列を含む単純なテーブルがあるとします。ここでは ID のみにインデックスを付けています。
Id (Int), Telephone_Number (Int), Name (VARCHAR), Address (VARCHAR)
以下のクエリを実行して、インデックスが使用されているかどうか、および I/O 呼び出しなしで効率的に実行されているかどうかを確認する必要があると想像してください。インデックスを作成しただけであることに注意してください。 Id
.
SELECT Id FROM mytable WHERE Telephone_Number = '55442233';
このクエリのパフォーマンスをチェックすると、がっかりするでしょう。 Telephone_Number
インデックスが作成されていないため、I/O 呼び出しを使用してテーブルから行をフェッチする必要があります。したがって、クエリ内にインデックスが作成されていない列があり、頻繁な I/O 呼び出しが発生するため、これはインデックスをカバーするものではありません。
カバードインデックスにするには、複合インデックスを作成する必要があります。 (Id, Telephone_Number)
.
詳細については、次のブログを参照してください。https://www.percona.com/blog/2006/11/23/covering-index-and-prefix-indexes/