4

SQL Server でテーブルのインデックスを処理する最善の方法を見つけようとしています。

読み取るだけのテーブルがあります。テーブルへの実際の書き込みはありません (初期設定後)。

テーブルには、インデックスを作成する必要がある約 5 ~ 6 列があります。テーブル全体に対して 1 つの非クラスター化インデックスを設定し、インデックスを作成する必要があるすべての列をそのインデックスに追加する方が理にかなっていますか?それとも、それぞれ 1 つの列を持つ複数の非クラスター化インデックスを設定する必要がありますか?

どのセットアップが読み取りパフォーマンスを向上させるのか疑問に思っています。

これに関するヘルプは素晴らしいでしょう。

アップデート:

すでにいくつかの良い答えがありますが、私のニーズについてもう少し詳しく説明したいと思います.

自動レコードを持つメイン テーブルが 1 つあります。1 億件を超えるレコードをすばやくカウントできるようにする必要があります。whereステートメントはさまざまですが、whereステートメントで可能なすべての列にインデックスを付けようとしています。したがって、次のようなクエリがあります。

SELECT COUNT(recordID)
FROM tableName
WHERE zip IN (32801, 32802, 32803, 32809) 
AND makeID = '32' 
AND modelID IN (22, 332, 402, 504, 620)

またはこのようなもの:

SELECT COUNT(recordID)
FROM tableName
WHERE stateID = '9' 
AND classCode IN (3,5,9) 
AND makeID NOT IN (55, 56, 60, 80, 99)

そのため、where 句に含めることができる列は約 5 ~ 6 列ありますが、どの列かによって大きく異なります。

4

2 に答える 2

6

The fewer indexes you have - the better. Each index might speed up some queries - but it also incurs overhead and needs to be maintained. Not so bad if you don't write much to the table.

If you can combine multiple columns into a single index - perfect! But if you have a compound index on multiple columns, that index can only be used if you use/need the n left-most columns.

So if you have an index on (City, LastName, FirstName) like in a phone book - this works if you're looking for:

  • everyone in a given city
  • every "Smith" in "Boston"
  • every "Paul Smith" in "New York"

but it cannot be used to find all entries with first name "Paul" or all people with lastname of "Brown" in your entire table; the index can only be used if you also specify the City column

So therefore - compound indexes are beneficial and desirable - but only if you can really use them! Having just one index with your 6 columns does not help you at all, if you need to select the columns individually

Update: with your concrete queries, you can now start to design what indexes would help:

SELECT COUNT(recordID)
FROM tableName
WHERE zip IN (32801, 32802, 32803, 32809) 
AND modelID = '32' 
AND model ID IN (22, 332, 402, 504, 620)

Here, an index on (zip, modelID) would probably be a good idea - both zip and modelID are used in the where clause (together), and having the recordID in the index as well (as an Include(RecordID) clause) should help, too.

SELECT COUNT(recordID)
FROM tableName
WHERE stateID = '9' 
AND classCode IN (3,5,9) 
AND makeID NOT IN (55, 56, 60, 80, 99)

Again: based on the WHERE clause - create an index on (stateID, classCode, makeID) and possibly add Include(RecordID) so that the nonclustered index becomes covering (e.g. all the info needed for your query is in the nonclustered index itself - no need to go back to the "base" tables).

于 2012-10-10T16:58:42.667 に答える
4

アクセスパターンによって異なります

読み取り専用テーブルの場合、複数の非クラスター化インデックスを作成する可能性が高く、それぞれに WHERE 句に一致する複数のキー列と、非キー列のINCLUDEd列があります

すべてのクラスター化されていないものも、列ごとに 1 つもありません。それらは役に立ちません。実際のクエリ

于 2012-10-10T16:56:22.733 に答える