2011-12-08 16 views
0

私は約550万レコードのテーブルを持っています。私は日付に基づいてそれからいくつかのレコードを削除する必要があります。私のクエリは次のようになります:削除に長時間かかる

DELETE FROM Table WHERE [Date] between '2011-10-31 04:30:23' and '2011-11-01 04:30:42' 

これは約9000行ですが、この操作は最後の非常に長い時間です。どうすればスピードアップできますか? Dateはdatetime2の型で、int主キーはクラスタ化されています。更新および削除トリガーは無効です。

+2

'[Date]'にインデックスがありますか? –

+0

列の名前をDate以外の名前に変更することを検討してください。予約語と同じ列名を使用することは決して**まったくありません。ある時点で痛みの世界に終わるだけです。それはあまりにも怠惰です - それは日付ではなく、それは創造期または投稿された日付またはsomesuchです。それに適切な名前を付けます。 – Cruachan

答えて

2

[日付]がすべての行の文字列にキャストされ、テーブル全体が順次スキャンされる可能性が非常に高いです。

代わりの日付にあなたのパラメータをキャストしてみてください:

DELETE FROM Table WHERE [Date] between convert(datetime, '2011-10-31 04:30:23') and convert(datetime, '2011-11-01 04:30:42') 

また、[Date]

+0

本当に助けになったインデックスを作成していただきありがとうございます。 – viki

+0

システムに他のユーザーがいない場合は、「with(holdlock)」が役立つ可能性があります。 – Paparazzi

1

上のインデックスはまずあなたが日付にインデックスを持っていることを確認してくださいがありますことを確認してください。

インデックスがある場合は、実行計画をチェックし、使用していることを確認します。索引を使用すると最も効率的な削除処理方法であることに常に注意する必要はないことに注意してください。大量のレコードを削除する場合(大雑把なルールが10%を超えている場合)フルスキャンよりも大きくすることができます。

大きなテーブルの場合、統計情報が最新であることを確認する価値があります(sp_updatestats)。データベースにテーブルの行数が誤っていると、実行計画に不適切な選択が行われるためです。たとえば、統計情報が不正確な場合、データベースに存在するレコードがテーブル内のレコード数よりもはるかに少ないと考えられるため、データベースはインデックスを無視することになります。日付の奇数分布にも同様の影響があります。

おそらく、インデックスを日付にドロップしてからもう一度作成してみてください。インデックスはバイナリツリーであり、効率的に動作するためには、それらをバランスさせる必要があります。データが時間とともに蓄積された場合、索引はうまくいきませんし、照会は適切なデータを見つけるのに時間がかかるかもしれません。この問題と統計の両方の問題は、データベース保守作業によって自動的に処理されるはずですが、しばしば見落とされます。

最後に、テーブルに他の多くのインデックスがあるかどうかは言いません。データベースがインデックスを再編成する際に、削除を進めるとともにインデックスを更新する際に、問題が発生している可能性があります。少し徹底的ですが、削除を実行する前にテーブルの他のすべてのインデックスを削除してから、再度作成してください。

+2

良い答え。言いたいことを忘れたもう一つのことは、外部キーの制約でした。子データがすでに削除されていることがわかっていてもチェックしなければなりません。これにより、削除が大幅に遅くなる可能性があります。 FKが多い場合は、小規模なバッチで削除する必要があります。 – HLGEM

+0

ありがとうございます、私は[Date]に新しいインデックスを作成しました。これは物事をスピードアップするのに役立ちました。私は[Date]を含むクエリを持っていないので([PK]にクラスタード・インデックスのみが存在していたので)、[Date]の前にインデックスはありませんでした。また、追加情報をありがとう、それは非常に便利です。 – viki

+0

@HGLEM。良い点、それを忘れてしまった。 – Cruachan

関連する問題