0

私たちの最大のテーブルには、約 7 Mio のレコードがあります。int 型の非クラスター化インデックスでテーブルをクエリすると、次のようになります。

例えば:

Select * from MyTable where TypeID = 401

-- 147000 行未満を表示するのに約 7 秒かかります。

Select * from MyTable where TypeID like '%401%'

-- 147000 行未満を表示するのに約 13 秒かかります。

ここでパフォーマンスを向上させる方法はありますか?例えば。より多くのメモリ?現在16GBあります。

私のテーブルスクリプト:

create table MyTable (ID int not null, Description nvarchar(50) not null, TypeID int not null, primary key (ID));

create index MyTable_TypeID on MyTable (TypeID);

編集:答えのほとんどは、実際には無視できる2番目のクエリを中心に展開しています。代わりに、最初のクエリにフォーカスする必要があります。データをより速く取得するためにできることはありますか?

4

3 に答える 3

0

インデックスに列を含めることができます (実際のインデックスではなく、リーフ ノード上)。これは、リーフ ノードで適切な一致を見つけた後、データを参照せず、ルックアップが必要ないため、しばらくの間は安全なはずです。

パフォーマンスのボトルネックは、すべての行で実行する必要がある一致チェックです。チェックが成功するかどうかは関係ありません。クエリが結果として行を返さない場合でも、一致が見つからないため、同じ大きさの時間が必要です。結果セットが大きく、その大量のデータをネット経由で転送する必要がある場合、もちろん悪影響もあります。

編集:結果セットのサイズが無関係であると主張して申し訳ありません

一致する ID ごとに、目的のフィールドを読み取る必要があります。それらがインデックスに含まれていない場合は、インデックスのリーフ要素にあるポインター (アドレス) を使用して、「通常の」テーブルから取得する必要があります。これらのフィールドを含めると、インデックス内でデータをすぐに利用できるようになります。

含まれる列を含むインデックスを作成する方法は次のとおりです

CREATE INDEX MyTable_TypeID on MyTable (TypeID)
INCLUDE (ID, Description, TypeID);

http://technet.microsoft.com/en-us/library/ms189607%28v=sql.105%29.aspxのように

挿入操作または更新操作では、このようなインデックスにはより多くのメンテナンスが必要になることに注意してください。ここでの利益はそこでの損失です。

于 2013-09-12T15:17:34.153 に答える
0

クエリ オプティマイザーでテスト
Like はシークをスキャンに変更します
ワイルド カードがなくても、
必要な場合は like を使用しないでください =

Select * from MyTable where TypeID = 401
-- index seek

Select * from MyTable where TypeID like 401
-- index scan 

Select * from MyTable where TypeID like '%401%'
-- index scan 

なぜそのような整数で検索するのですか?

列が char の場合、
「value」は引き続きインデックス シークになります。
「value%」は引き続きインデックス シークになり
ます。「%value」は引き続きインデックス スキャンになります。

于 2013-09-12T16:52:39.953 に答える
0
Select * from MyTable where TypeID like '%401%'

このクエリはインデックスを使用できないため、テーブル全体を調べる必要があるため、処理が遅くなります。何らかの方法で回避できる場合は、where 条件の最初の文字としてワイルドカードを使用しないでください。特にこれは整数フィールドであるため、より良い設計で回避できるはずです。

于 2013-09-12T17:01:02.143 に答える