3

[lastName]と[firstName]の2つの列にこの順序で単一のインデックスを作成した場合。次に、クエリを実行して、ダニエルという名の人の数を見つけます。

SELECT count(*)
FROM people
WHERE firstName = N'daniel'

これは、最初のインデックス(lastname)の各セクションを検索し、2番目のインデックス(firstName)を使用して、LastNameエントリの各ブロックをすばやく検索しますか?

これは当たり前のことのように思えます。私はそれが起こっていることだと思いますが、あなたは彼らが仮定について何を言っているか知っています。

4

2 に答える 2

4

はい、クエリオプティマイザが、(フルスキャンを実行するよりも)「LastNameエントリの各ブロックをすばやく検索する」方がよいと判断した場合、このクエリはこのインデックスを使用する可能性があります(おそらく使用します)。 )テーブルの。

ただし、この特定のクエリではインデックスの(firstName)方が効率的であるため、そのようなインデックスがある場合、SQL-Serverはそのインデックスを使用します(そしてインデックスシークを実行します)。


SQL-Server 2008 R2、Expressエディションでテスト済み:

CREATE TABLE Test.dbo.people
( lastName  NVARCHAR(30) NOT NULL
, firstName NVARCHAR(30) NOT NULL
) ;

INSERT INTO people 
VALUES
('Johnes', 'Alex'),
...                   --- about 300 rows
('Johnes', 'Bill'),
('Brown', 'Bill') ;

インデックスなしのクエリ、テーブルスキャン

SELECT count(*)
FROM people
WHERE firstName = N'Bill' ;

ここに画像の説明を入力してください


インデックスをオンにしてクエリを実行し(lastName, firstName)インデックススキャン

CREATE INDEX last_first_idx
ON people (lastName, firstName) ;

SELECT ...

ここに画像の説明を入力してください

インデックスをオンにしてクエリを実行し(firstName)インデックスシーク

CREATE INDEX first_idx
ON people (firstName) ;

SELECT ...

ここに画像の説明を入力してください

于 2012-08-02T08:58:00.313 に答える
2

(lastname、firstname)にこの順序でインデックスがある場合、次のようなクエリ

WHERE firstname = 'daniel'

WHERE複合インデックスの最初の列(つまり姓)を句に含めない限り、インデックスは使用されません。名のみを効率的に検索するには、その列に別のインデックスが必要です。

両方の列を頻繁に検索する場合は、2つの別々の単一列インデックスを実行してください。ただし、各インデックスは挿入/更新時に更新されるため、パフォーマンスに影響することに注意してください。

また、同時にインデックスをカバーしていない場合は、複合インデックスを避けてください。複合インデックスに関するヒントについては、sql-server-performance.comの次の記事を参照してください。

SQLServer複合インデックスを最適化するためのヒント

更新(反対票に対処するため):

インデックスのこの特定のケースでSELECT Count(*)は、(コメントの@ypercubeで指摘されているように)カバーインデックスであるため、オプティマイザーは実行用にそれを選択できます。この場合にインデックスを使用するということはIndex Scan、ではなくを意味しIndex Seekます。

Index Scan実行とは、インデックス内のすべての行をスキャンすることを意味します。インデックスに含まれる行がテーブル全体よりも少ない場合、これは高速になります。したがって、非常に選択的なインデックス(多くの一意の値を持つ)を取得した場合、テーブル自体とほぼ同じ数の行を持つインデックスを取得します。Clustered Index Scanこのような場合、通常、 (テーブル上のPKを意味し、PKを反復処理する)またはNon-Clustered Index Scan(インデックスを反復処理する)を実行しても大きな違いはありません。A Table Scan(@ypercubeの回答のスクリーンショットに見られるように)は、テーブルにPKがないことを意味します。これはClustered Index Scan、PKによって与えられるディスク上のシーケンシャルデータアライメントの利点がないため、実行がさらに遅くなる結果になります。 。

于 2012-08-02T08:31:51.193 に答える