質問

私はSQL Serverを使用しており、キールックアップの概念をよく見てきました。

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

したがって、キールックアップがある場合は、選択ステートメントにある非インデックス列をカバーする「include」列を備えたインデックスを作成できます。

例えば、

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番目のインデックスが必要であることをどのようにして知っていますか?また、あまりにも多くのインデックスを追加しようとしているのはどの時点で、それだけの価値がないことを知っていますか?

一部のクエリには、インデックススキャン、キールックアップを含めることができ、それでも非常に速くパフォーマンスがあるように思えます。

役に立ちましたか?

解決

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

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

本の中ですべてのファーリーを見つけて、彼らの住所に興味があるなら、必要なのは白いページだけです。 Farleys(FSを見つけるなど)をすばやく探すことができ、必要なすべての情報を手に入れることができます。

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

そして、しきい値があります。ある時点で、データベースは、クラスター化されたインデックスのすべてのページを通過するだけで迅速であることを認識し、すべてのレコードをチェックして関心があるかどうかを確認します。

真剣に - ルックアップを取り除きます。あなたのクエリは今高速になるかもしれませんが、おそらく拡大しないでしょう。

他のヒント

バックグラウンド

の中に 最悪の場合, 、ルックアップを含むクエリは、非クラスター化されたインデックスでカバーされていない列データを必要とする行の物理ストレージに移動する必要があります。の中に 非常に最悪です 最悪の場合、各検索には個別のI/Oが必要になり、実行する前にその単一行のデータが戻ってくるのを実行する必要があります。このシナリオは通常、ルックアップが処理する必要がある場合に深刻なパフォーマンスの影響を及ぼします 重要 行の数。

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

SQL Server 2000+では、クエリで必要な有用な順序付けおよび/または(ほとんどの)列を提供する非クラスター化インデックスがあり、非クラスター化されたインデックスとパフォーマンスを使用して、検索数が比較的小さくなる可能性が高い場所があります。 a 限られた数 ベーステーブルのルックアップは、利用可能な最も安価なアクセス方法である可能性があります(もちろん、完全にカバーする非クラスター化されたインデックスはまだ安価かもしれません)。

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

それ以外の場合は、十分なだけでいくつかの追加のインデックス(おそらくSQL Server 2008+でフィルタリングされている)を作成することができます INCLUDE データ変更のパフォーマンスをあまり妥協することなく、追加のディスク容量をあまり使用することなく、パフォーマンス批判的なクエリの大部分を満たすための列。競合する考慮事項のバランスをとることは、科学よりもインデックスチューニングをより多くのアートにするものです。

費用

ルックアップオペレーターの99%のコストは本当に何ですか 意味 クエリプランで。クエリオプティマイザーの原価計算コンポーネントは、anを生成します 推定 合計の99%であるその操作のコスト 推定 クエリ用。数(0.29)は、それほど意味はありません。すべての実用的な目的のために、その特定のクエリの代替戦略を比較する際に、オプティマイザーが内部的に使用する単位の数字としてそれを考慮する必要があります。

推定コストは、ハードウェア、構成、アプリケーションのニーズ、またはその他のものを考慮しません。オプティマイザーが使用するコストモデルには、かなりの数のヒューリスティックと、その仮定を簡素化することが含まれています 起こる ほとんどの場合、ほとんどのクエリの場合、ほとんどのハードウェアで合理的な計画を作成します。それはあると言っているわけではありません いいえ 計画とパフォーマンスにおける高コストのオペレーター間の相関。むしろ、リンクは一般に予想されるよりもはるかに弱いことがよくあります。ぜひ、高推定のコスト計画オペレーターの理由を最初に確認しますが、情報を非常に欠陥のある見積もり以外のものとして扱わないでください。

影響

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

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

明示的な種類の有無にかかわらず、ネストされたループはルックアップを運転することに参加します WithOrderedPrefetch また WithUnorderedPrefetch 属性が存在します。どちらの場合でも、クエリ実行エンジンは、ルックアップと問題を推進するインデックスキーストリームで「先を見据えて」 読み取り 読みます。アイデアは発行することです 非同期 すぐに必要になるデータページのI/Oシステムへのリクエストを読み取ります。そのため、検索にはデータページが必要になるまでに、すでにメモリに存在しています。

理想的な条件(低断片化、良好なクエリプラン、高性能I/Oシステム)では、読み取りメカニズムは、I/Oが完了するのを待つことを大規模な並列クエリプランでさえ防ぐのに十分な速さである可能性があります。これは、非常に大きな単一のI/O要求を発行することができるEnterprise Editionで特に当てはまります(メモリが提供される場合、リクエストごとに最大2MB)。一方、理想的ではない(より通常!)条件下では、長いI/Oキューで待っているときにクエリが恐ろしく苦しむか、I/Oシステムを十分に強く駆動できない場合があります。キールックアップの最悪のパフォーマンスは、実際には非常に貧弱です。

概要

要約すると、あなたはそうします 一般的 検索を避けたい そうするのが理にかなっているところ. 。小さなクエリ(小さいままになる)の場合、システムとそのユーザーのより広いニーズに重いことを考えると、追加のインデックス(スペースとメンテナンス)のオーバーヘッドが正当化されないと判断することができます。

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

ライセンス: CC-BY-SA帰属
所属していません dba.stackexchange
scroll top