私のsqlServer2008テーブルには500万を超えるレコードがあります。1つのステートメントで400万を超えるレコードを削除しています。1時間以上かかります。これはレコードを削除するのに最適なクエリですか?
私の削除クエリ
delete From [Table]
where SUBSTRING([Column_YYY],1,CHARINDEX(N'',[Column_YYY])-1) = '4'
私のsqlServer2008テーブルには500万を超えるレコードがあります。1つのステートメントで400万を超えるレコードを削除しています。1時間以上かかります。これはレコードを削除するのに最適なクエリですか?
私の削除クエリ
delete From [Table]
where SUBSTRING([Column_YYY],1,CHARINDEX(N'',[Column_YYY])-1) = '4'
いいえ、それは決して最良のクエリではありません。サブストリングは1で始まり、SINGLE文字と比較しています'4'
。ColumnYYYでインデックスを使用するには、それをLIKE句に変更するだけで、インデックスが最初の2文字をすばやく検索できるようになります。
delete [Table]
where [Column_YYY] LIKE N'4%'
これは、テーブルの80%をターゲットにしていない場合に当てはまります。その場合、SQLServerはとにかくテーブルを完全にスキャンします。tempdbスペースの問題や過度に大きなトランザクション(ロック)を防ぐために、私はそれをビットに分割しました:
set nocount on
select 1;
while @@rowcount > 0
begin
;with x as (select top 100000 * from [Table] where [Column_YYY] LIKE N'4%')
delete x;
end;
これは、クエリがDBのすべての行でSUBSTRING関数を実行して、条件に一致するかどうかを確認する必要があるためです。WHERE句の関数は常に避ける必要があります。インデックスがあっても使用されません。
それだけの時間がかかり、それが一般的な操作である場合は、その値の結果をDBに保持し、その値にインデックスを作成することを検討してください。
編集:メインの質問とは関係ありませんが、それでも議論の一部です。インデックスの使用法: