2

したがって、InventoryListItemsいくつかの列を持つテーブルがあります。特定の列(、外部キー)に基づいて行を検索するg_list_idことがあるため、その外部キー列を、と呼ぶ非クラスター化インデックスに配置しますMYINDEX

したがって、次のようなデータを検索すると、次のようになります。

-- fake data for example
DECLARE @ListId uniqueidentifier
SELECT @ListId = '7BCD0E9F-28D9-4F40-BD67-803005179B04' 

SELECT *
FROM [dbo].[InventoryListItems]
WHERE [g_list_id] = @ListId

MYINDEXインデックスを使用して必要な行だけを検索し、それらの行の情報を検索することを期待していました。したがって、インデックス自体で必要なものをすべて見つけるほど良くはありませんが、テーブルのフルスキャンを実行するよりも大きなメリットがあります。

しかし、代わりに、クラスター化されたインデックススキャンをまだ取得しているようです。なぜそうなるのか理解できません。

インデックスのインクルードされた列の値のみをSELECTするようなことをすると、期待どおりのインデックスシークが実行され、インデックスからすべてがプルされます。

しかし、私SELECT *がそうだとしたら、WHERE句で参照されているため、インデックスを使用することで大きなメリットが得られると思われる場合に、インデックスを取得してスキャンを実行するのはなぜですか?

4

1 に答える 1

2

を実行しているため、すべての列SELECT *を取得するため、SQL Serverのクエリオプティマイザーは、クラスター化インデックスのスキャンを実行する方が簡単で効率的であると判断した可能性があります。とにかくすべての列を取得するには、クラスター化インデックスリーフレベルに移動する必要があるためです。 (最初にシークを実行し、次にキールックアップを実行して実際にデータページ全体を取得することは、非常にコストのかかる操作です。このセットアップでは、スキャンの方が効率的かもしれません)。

やってみればほぼ間違いない

SELECT g_list_id
FROM [dbo].[InventoryListItems]
WHERE [g_list_id] = @ListId

次に、代わりにインデックスシークがあります(すべてではなく単一の列のみを取得しているため)。

これが、使用時に特に注意することをお勧めする理由の1つですSELECT * ....。可能な限り、使用しないようにしてください。

于 2012-09-25T15:23:54.197 に答える