web-dev-qa-db-ja.com

キールックアップの削減

私はSQLサーバーを使用しており、キールックアップの概念を詳しく調べています。

http://blog.sqlauthority.com/2009/10/07/sql-server-query-optimization-remove-bookmark-lookup-remove-rid-lookup-remove-key-lookup/

したがって、キールックアップがある場合は、 'include'列を使用してインデックスを作成し、selectステートメントにある非インデックス列をカバーできます。

例えば、

SELECT ID, FirstName FROM OneIndex WHERE City = 'Las Vegas'
GO

このインデックスにはキールックアップが含まれます。

CREATE NONCLUSTERED INDEX [IX_OneIndex_City] ON [dbo].[OneIndex]
(
[City] ASC
) ON [PRIMARY]
GO

しかし、これはキールックアップを削除します、

CREATE NONCLUSTERED INDEX [IX_OneIndex_Include] ON [dbo].[OneIndex]
(
City
) INCLUDE (FirstName,ID) ON [PRIMARY]
GO

これはパフォーマンスにどの程度の影響があるのでしょうか?キールックアップのオペレーターコストは0.295969(99%)ですが、それは実際にはどういう意味ですか?

そこに2番目のインデックスが必要であることをどのようにしてわかりますか。また、インデックスを追加しすぎて価値がない場合はどの時点で判明するのでしょうか。

一部のクエリにはインデックススキャン、キールックアップを含めることができますが、それでも非常に高速に実行されるようです。

6
peter

電話会社が電話番号のリストを持っているとします。これには、顧客が誰であるか、彼らが住んでいる場所、請求番号などが含まれます。主キーは電話番号である可能性があります。

彼らはあなたにホワイトページを与えます。これは、アドレスなどの列を含む、名前順に並べられた非クラスター化インデックスのようなものです。

あなたが本の中ですべてのファーリーを見つけたいと思っていて、彼らの住所に興味があるなら、白いページで十分です。 Farleysにすばやくシークして(Fを見つけるなど)、必要な情報をすべて入手できます。

ただし、請求番号が必要な場合は、ルックアップを行う必要があります。 Farleysのすべての電話番号をすばやく見つけることができますが、その後、それぞれ(数百)を取得し、メイン(クラスター化)インデックスで別のSeek(ルックアップ)を実行する必要があります。これは、電話番号順に並べられています。それらのそれぞれは、Farleysを見つけるためのシークとほぼ同じコストであり、クエリの実行を桁違いに悪化させます。

そして、しきい値があります。ある時点で、データベースは、クラスター化インデックスのすべてのページを調べ、すべてのレコードを調べて、それが重要かどうかを確認する方が速いことに気づきます。

真剣に-ルックアップを取り除く。クエリは今は高速かもしれませんが、おそらくスケーリングされません。

7
Rob Farley

バックグラウンド

最悪の場合では、ルックアップを含むクエリは、非クラスター化インデックスでカバーされていない列データを必要とする行の物理ストレージに移動する必要があります。最悪の場合very worstの場合、ルックアップごとに個別のI/Oが必要になり、実行する前に、その1行分のデータが返されるまで待機する必要があります。このシナリオでは、ルックアップでsignificant行数を処理する必要がある場合、通常、パフォーマンスに重大な影響があります。

ルックアップがこのような悪い報道をするのはそのためです。一方、ルックアップを実行する機能がSQL Server 2000で導入されたことを考慮してください。SQLServer 7.0では、クエリプロセッサはallクエリを満たすために必要な情報を含む場合にのみ非クラスタ化インデックスを使用できました。 ;それ以外の場合はすべて、クラスター化インデックス(存在する場合は、それ以外の場合はヒープスキャン)を介してデータにアクセスする必要がありました。ルックアップが常に非常に悪かった場合、SQL Serverがルックアップを導入することはなかったでしょう。

SQL Server 2000以降では、クエリに必要な順序付けや列(またはそのほとんど)を提供する非クラスタ化インデックスがあり、非クラスタ化インデックスを使用して実行するルックアップの数が比較的少ない場合、 a 制限された数ベーステーブルでのルックアップの数は、利用可能な最も安価なアクセス方法である可能性があります(もちろん、完全にカバーされた非クラスター化インデックスの方が安い場合があります)。

多くの場合、すべての一般的なクエリのベーステーブルをスキャンしないようにするために必要な数の非クラスター化インデックスを作成するのは、単に実用的ではありませんです。その理由の1つはINSERT/UPDATE/DELETE/MERGEパフォーマンスはクエリ速度よりも重要です(データ変更操作では、影響を受けるすべての非クラスター化インデックスも維持する必要があることに注意してください)。もう1つの理由はスペースです。各非クラスター化インデックスは、ベーステーブルの列のサブセット(またはその式)のコピーを表します。データのコピーが増えると、ストレージスペースも増え、SQL Serverのメモリ内データキャッシュのスペースを奪い合うことも増えます。

また、データ変更のパフォーマンスを過度に低下させることなく、パフォーマンスが重要なクエリの大多数を満たすのに十分なINCLUDE列を使用して、いくつかの追加のインデックス(おそらくSQL Server 2008+でフィルター処理される)を作成できます。余分なディスク領域を使いすぎずに。競合する考慮事項のバランスをとることが、インデックスのチューニングを科学よりもアートに近づける理由です。

費用

クエリプランで、ルックアップ演算子の99%のコストが実際にmeansであることを尋ねます。クエリオプティマイザーのコスト計算コンポーネントは、クエリの合計推定の99%であるその操作の推定コストを生成します。数値自体(0.29)は、あまり意味がありません。すべての実用的な目的のために、その特定のクエリの代替戦略を比較するときに、オプティマイザが内部で使用する単位なしの数と見なす必要があります。

推定コストには、ハードウェア、構成、アプリケーションのニーズなど、ほとんど何も考慮されていません。オプティマイザーが使用するコストモデルには、ほとんどのハードウェアでほとんどのクエリに対して、ほとんどの場合、妥当な計画を作成するためのhappenという多数のヒューリスティックと簡略化の仮定が含まれています。計画の高コスト演算子とパフォーマンスの間にno相関があると言っているのではありません。むしろ、リンクは通常予想されるよりもはるかに弱いことがよくあります。必ず、見積もられた高額プランのオペレーターの理由を最初に確認してください。ただし、情報に、欠陥がある可能性のある見積もり以外のものとして扱わないでください。

影響

また、ルックアップの影響を改善できるいくつかの要因についても触れておきます。最初に、冒頭で、最悪の場合は行ごとの物理I/Oが関係することを述べました。ルックアップを満たすために必要なデータページ(クラスター化インデックスまたはヒープ)が既にメモリ(データキャッシュ)にある場合、これは明らかに回避されます。この場合、ルックアップを使用するプランとカバリングインデックスを使用したプランの実行時間の差は、計り知れないものになる可能性があります。物理I/Oが必要な場合でも、読み取りの数が少ない場合でも、気にしない場合があります。 (テーブルのデータページがデータキャッシュに含まれる可能性は、多くの要因に依存し、ハードウェアや状況によって異なります)。

物理的なI/Oが少しだけ必要な場合でも、クエリプランに存在する最適化によって、ルックアップの影響が軽減される場合があります。 SQL Serverがルックアップの数が重要であると予想する場合、ネストされたループ結合に入る行を明示的にソートして、非クラスター化キーの順にルックアップを駆動することを選択できます。この並べ替えにより、非クラスター化インデックスの順次読み取りが促進されます。これは、ハードウェアでのランダムI/Oよりもはるかに高速です。

明示的なソートの有無にかかわらず、ルックアップを駆動するネストされたループ結合には、WithOrderedPrefetchまたはWithUnorderedPrefetch属性が存在する場合があります。どちらの場合でも、クエリ実行エンジンは、ルックアップを実行するインデックスキーストリームを「先読み」し、read-ahead読み取りを発行します。アイデアは、すぐに必要になるデータページに対してI-Oシステムに非同期読み取り要求を発行することです。これにより、ルックアップでデータページが必要になるまでに、メモリ内にすでに存在しています。

理想的な条件(断片化が少なく、クエリプランが適切で、高性能のI/Oシステム)の場合、先読みメカニズムは、大規模な並列クエリプランでさえI/Oの完了を待たないように十分高速である可能性があります。これは、非常に大きな単一のI/O要求を発行できるEnterprise Editionで特に当てはまります(メモリが機能する場合、要求ごとに最大2MB)。一方、理想的ではない(より正常な!)状態では、クエリが長いI/Oキューで待機するか、I/Oシステムを十分に駆動できないため、クエリがひどく損なわれる可能性があります。キールックアップの最悪の場合のパフォーマンスは、実際には非常に悪い場合があります。

概要

要約すると、あなたは一般に検索を避けたいそうすることが理にかなっている場合です。小さいクエリ(小さいままになる)の場合、システムとそのユーザーの幅広いニーズに応じて、余分なインデックス(スペースとメンテナンス)のオーバーヘッドが正当化されない場合があります。

結局のところ、これはすべて、データベースの開発と管理である芸術と科学の一部です。

12
Paul White 9