web-dev-qa-db-ja.com

テーブルが非常に大きいと、アプリケーションのパフォーマンスが非常に遅くなります

パフォーマンスに問題がある古いアプリケーションがあります。私はそれを、システム内の確実に注意が必要ないくつかのスポットに絞り込みます。

このアプリで参照されている1つのテーブルが見つかり、1,332,730,786レコードが含まれています。

Table IDSelection 
IDType varchar(20) NOT NULL, 
SelectID int NOT NULL, 
UnID int NOT NULL, 
Batch int NULL

テーブルには次のインデックスがあります

IX_IDSelection_UnID nonclustered located on PRIMARY UnID
PK_UIDSelection clustered, unique, primary key located on PRIMARY SelectID, IDType, UnID

私の懸念は1です。このテーブルには、空の文字列(ただしNULLではない)であるIDTypeのいくつかのエントリを持つ複合主キーがあります。 2.このテーブルに対して以下のような単純なSELECTクエリを実行すると、かなり時間がかかります。

select * from IDSelection where IDType <> '' and Batch is not NULL ORDER by Batch desc  -- cluster index scan
select * from IDSelection where Batch = 9977    -- 8 minutes run for 19 records
select * from IDSelection where IDType = 'ParentID' and Batch is not NULL  -- 9 min 3614603 rows

以下のようにWHERE句でインデックス付きのUnIDを使用すると、パフォーマンスが向上します

SELECT * FROM IDSelection where UnID = 1093510

インデックスの断片化はここでは問題になりません。 IDの主キーを追加し、[非クラスター化一意インデックス]のヘルプとして現在の複合キーを作成するのに役立ちますか?他にどのようなオプションがありますか?

DBバージョンはMS SQL 2014 Enterpriseです

1
user1706426

追加のインデックスを作成するのにどのくらい時間がかかると思いますか? DMLはどのくらいの頻度で実行されますか?このテーブルは頻繁に読み取られていますか?

この怪物には10億行以上あるので、列SelectID, IDType, UnID, Batchそして適切なインデックスをそこに適用します。

1
Jozekban

これらには、Batchで始まるインデックスが必要です。最初の場合は_ORDER BY_、2番目の場合はWHEREです。

_select * from IDSelection where IDType <> '' and Batch is not NULL ORDER by Batch desc  -- cluster index scan
select * from IDSelection where Batch = 9977    -- 8 minutes run for 19 records
_

これにはINDEX(ParentID, Batch)がこの順序で必要です:

_select * from IDSelection where IDType = 'ParentID' and Batch is not NULL  -- 9 min 3614603 rows
_

あなたはすでにUnIDにインデックスを持っています(または少なくともそれから始まっています)、したがってこれは高速です:

_SELECT * FROM IDSelection where UnID = 1093510
_

すべての列が本当に必要な場合を除き、_*_を使用しないでください。列の小さなセットのみを選択する必要がある場合は、それらをインデックスの最後に追加して、「カバー」することができます。

0
Rick James