7

素晴らしい挿入パフォーマンスを備えた10億行を少し超える時系列データのテーブルがありますが、(場合によっては)選択パフォーマンスがひどいです。

tblTrendDetails(PKは示されているように順序付けられています):

PK  TrendTime    datetime
PK  CavityId     int
PK  TrendValueId int
    TrendValue   real

テーブルは継続的に新しいデータをプルし、古いデータをパージしているため、挿入と削除のパフォーマンスを維持する必要があります。

次のようなクエリを実行すると、パフォーマンスが低下します(30秒)。

SELECT * 
FROM tblTrendDetails
WHERE TrendTime BETWEEN @inMinTime AND @inMaxTime
  AND CavityId = @inCavityId
  AND TrendValueId = @inTrendId

同じクエリを再度実行すると(同じ時間ですが、またはのいずれ@inCavityId@inTrendId)、パフォーマンスは非常に良好です(1秒)。パフォーマンスカウンターは、クエリが最初に実行されたときにディスクアクセスが原因であることを示しています。

挿入または削除のパフォーマンスに(大幅に)悪影響を与えることなくパフォーマンスを向上させる方法に関する推奨事項はありますか?任意の提案(基盤となるデータベースの完全な変更を含む)を歓迎します。

4

1 に答える 1

9

同じまたは類似のデータの後続のクエリがはるかに高速に実行されるという事実は、SQLServerがデータをキャッシュしていることが原因である可能性があります。そうは言っても、この最初のクエリを高速化することは可能ですか?

クエリプランを確認します。

私の推測では、クエリはインデックススキャン(またはさらに悪いことに、テーブルスキャン)ではなくインデックスシークになるはずです。SET SHOWPLAN_TEXT ON;または同様の機能を使用してこれを確認してください。クエリを使用する場合betweenと同様に、クラスター化インデックスを実際に利用する必要がありますが、それについては議論の余地があります。=

インデックスの断片化:

これらの挿入と削除をすべて行った後、クラスター化インデックス(この場合は主キー)がかなり断片化されている可能性があります。私はおそらくこれをでチェックするでしょうDBCC SHOWCONTIG (tblTrendDetails)

テーブルのインデックスは。でデフラグできますDBCC INDEXDEFRAG (MyDatabase, tblTrendDetails)。これには時間がかかる場合がありますが、テーブルにアクセスできるようになり、厄介な副作用なしに操作を停止できます。

さらに進んでを使用する必要があるかもしれませんDBCC DBREINDEX (tblTrendDetails)。ただし、これはオフライン操作であるため、テーブルにアクセスする必要がない場合にのみこれを実行する必要があります。

ここで説明するいくつかの違いがあります:Microsoft SQLServer2000インデックスの最適化のベストプラクティス

大きなテーブルをデフラグすると、トランザクションログがかなり大きくなる可能性があり、時間がかかる可能性があることに注意してください。

パーティション化されたビュー:

これらが状況を改善しない場合(または断片化が問題にならない場合)、さまざまな範囲のレコードの基になるベーステーブルの束を作成し、それらをすべてビューに結合するパーティションビューを確認することもできます。 (元のテーブルを置き換えます)。

より良いもの:

これらの選択のパフォーマンスが実際のビジネスニーズである場合は、より優れたハードウェア(より高速なドライブ、より多くのメモリなど)を主張できる可能性があります。ドライブが2倍高速である場合、このクエリは半分の時間で実行されます。 ?また、これはうまくいかないかもしれませんが、SQL Serverの新しいバージョンは、オプションが多く、保守が優れているため、本当に高速であることがわかりました。会社のデータのほとんどを2008R2に移動できてうれしいです。しかし、私は逸脱します...

于 2012-10-23T21:04:08.233 に答える