84

タイムアウトしているこのようなステートメントがあります:

DELETE FROM [table] WHERE [COL] IN ( '1', '2', '6', '12', '24', '7', '3', '5')

私はこのように一度に1つずつやってみました:

DELETE FROM [table] WHERE [COL] IN ( '1' )

これまでのところ、22分でまだ進行中です。

テーブルには260,000行あり、4列です。

なぜこれがとても遅いのか、そしてそれをどのようにスピードアップするのか、誰かが何か考えを持っていますか?WHEREを実行している[COL]には、一意ではない、クラスター化されていないインデックスがあります。SQL Server2008R2を使用しています

更新:テーブルにトリガーがありません。

4

15 に答える 15

98

削除が遅くなる原因となる可能性があるもの:

  • たくさんのレコードを削除する
  • 多くのインデックス
  • 子テーブルの外部キーにインデックスがありません。(コメントでこれについて言及してくれた@CesarAlvaradoDiazに感謝します)
  • デッドロックとブロッキング
  • トリガー
  • カスケード削除(削除する10個の親レコードは、何百万もの子レコードが削除されることを意味する可能性があります)
  • 拡大する必要のあるトランザクションログ
  • チェックする多くの外部キー

したがって、ブロックしているものを見つけて修正するか、通常の本番環境の負荷に干渉しない時間外に削除を実行するかを選択します。削除はバッチで実行できます(トリガー、カスケード削除、または多数のレコードがある場合に便利です)。インデックスを削除して再作成できます(営業時間外でも作成できる場合に最適です)。

于 2012-06-05T17:09:32.913 に答える
74
  1. CONSTRAINTを無効にする

    ALTER TABLE [TableName] NOCHECK CONSTRAINT ALL;

  2. インデックスを無効にする

    ALTER INDEX ALL ON [TableName] DISABLE;

  3. インデックスの再構築

    ALTER INDEX ALL ON [TableName] REBUILD;

  4. CONSTRAINTを有効にする

    ALTER TABLE [TableName] CHECK CONSTRAINT ALL;

  5. もう一度削除

于 2015-07-10T03:49:57.613 に答える
26

多くの行を削除すると、非常に時間がかかる場合があります。次のように、一度にいくつか削除してみてください。

delete top (10) YourTable where col in ('1','2','3','4')
while @@rowcount > 0
    begin
    delete top (10) YourTable where col in ('1','2','3','4')
    end
于 2012-06-05T16:48:31.853 に答える
5

私の場合、データベース統計が破損していました。ステートメント

delete from tablename where col1 = 'v1' 

一致するレコードがないのに30秒かかっていましたが

delete from tablename where col1 = 'rubbish'

すぐに走った

ランニング

update statistics tablename

問題を修正しました

于 2018-10-11T13:36:49.357 に答える
4

予防処置

SQL Profilerこの問題の根本的な原因については、の助けを借りて確認してください。Triggers実行の遅延が発生している可能性があります。何でもかまいません。Database Nameを選択することを忘れないでください。Object Name開始時に、Trace不要なクエリのスキャンを除外してください。

データベース名のフィルタリング

テーブル/ストアドプロシージャ/トリガー名のフィルタリング

是正処置

あなたが言ったように、あなたのテーブルには260,000レコードが含まれています...そしてIN Predicate6つの値が含まれています。現在、各レコードは、の各値に対して260,000回検索されていますIN Predicate。代わりに、以下のような内部結合である必要があります...

Delete K From YourTable1 K
Inner Join YourTable2 T on T.id = K.id

またはにIN Predicate値を挿入しますTemporary TableLocal Variable

于 2012-06-05T16:55:47.400 に答える
3

削除しようとしているテーブルにBEFORE/AFTER DELETEトリガーがある場合、そこに何かが原因で遅延が発生している可能性があります。

さらに、そのテーブルを参照する外部キーがある場合、追加のUPDATEまたはDELETEが発生している可能性があります。

于 2012-06-05T16:45:58.123 に答える
3

他のテーブルが[テーブル]にFK制約を持っている可能性があります。したがって、DBはこれらのテーブルをチェックして、参照整合性を維持する必要があります。これらのFKに対応する必要なインデックスがすべてある場合でも、それらの量を確認してください。

NHibernateが同じ列に重複したFKを誤って作成したが、名前が異なる(SQL Serverで許可されている)という状況がありました。DELETEステートメントの実行が大幅に遅くなりました。

于 2015-12-07T09:06:41.830 に答える
1

この削除ステートメントの実行プランを確認してください。インデックスシークが使用されているかどうかを確認してください。また、colのデータ型は何ですか?

間違ったデータ型を使用している場合は、updateステートメントを変更してください(「1」から1またはN「1」など)。

インデックススキャンを使用する場合は、クエリヒントの使用を検討してください。

于 2012-06-06T08:26:53.417 に答える
0

[COL]は本当に数字を保持する文字フィールドですか、それとも値の前後の単一引用符を取り除くことができますか?@Alexは、INが=よりも遅いということは正しいので、これを実行できれば、次のようになります。

DELETE FROM [table] WHERE [COL] = '1'

しかし、行を見つけるために文字列ではなく数字を使用する方が良いでしょう(SQLは数字が好きです):

 DELETE FROM [table] WHERE [COL] = 1

多分試してみてください:

 DELETE FROM [table] WHERE CAST([COL] AS INT) = 1

いずれの場合も、テーブルスキャンを高速化するために、列[COL]にインデックスがあることを確認してください。

于 2012-06-05T17:59:04.803 に答える
0

この記事を読んだので、あらゆる種類の不便をトラブルシューティングするのに本当に役立ちました

https://support.microsoft.com/en-us/kb/224453

これはwaitresourceKEYの場合です:16:72057595075231744(ab74b4daaf17)

-- First SQL Provider to find the SPID (Session ID)

-- Second Identify problem, check Status, Open_tran, Lastwaittype, waittype, and waittime
-- iMPORTANT Waitresource select * from sys.sysprocesses where spid = 57

select * from sys.databases where database_id=16

-- with Waitresource check this to obtain object id 
select * from sys.partitions where hobt_id=72057595075231744

select * from sys.objects where object_id=2105058535
于 2015-10-22T20:27:40.490 に答える
0

一部のレコードを選択するのではなく、テーブル内のすべてのレコードを削除する場合は、テーブルを削除して再作成する方がはるかに高速な場合があります。

于 2017-03-20T21:13:46.630 に答える
0

これを書いている約5〜4年前に私たちのクライアントにセットアップされたSSISパッケージ(SQL Serverの実行が非常に遅いため)を調べたところ、次のタスクがあることがわかりました:1 )XMLファイルから[Importbarcdes]というテーブルにデータを挿入します。

2)上記のテーブルをソースとして使用して、別のターゲットテーブルでコマンドをマージします。

3)「[Importbarcodes]から削除」。SSISパッケージのタスクによってXMLファイルが読み取られた後に挿入された行のテーブルをクリアします。

簡単に調べた後、1行しかないテーブルImportBarcodesのすべてのステートメント(SELECT、UPDATE、DELETEなど)の実行には約2分かかりました。

拡張イベントでは、多くのPAGEIOLATCH_EX待機通知が表示されました。

テーブルのインデックスは存在せず、トリガーは登録されていません。

テーブルのプロパティを詳しく調べると、[ストレージ]タブと[一般]セクションで、[データスペース]フィールドに、ページに割り当てられた6ギガバイトを超えるスペースが表示されました。

どうしたの:

クエリは過去4年間、毎日かなりの時間実行され、テーブル内のデータを挿入および削除し、未使用のページファイルを解放せずに残しました。

したがって、これが、拡張イベントセッションによってキャプチャされた待機イベントとテーブル上でゆっくりと実行されたコマンドの主な理由でした。

実行ALTER TABLE ImportBarcodes REBUILDすると、未使用のスペースがすべて解放される問題が修正されました。TRUNCATE TABLE ImportBarcodesすべてのページファイルとデータを削除するという唯一の違いを除いて、同様のことを行いました。

于 2019-07-26T12:59:01.470 に答える
0

古いトピックですが、1つはまだ関連しています。別の問題は、インデックスがヘルプよりも問題になる程度に断片化された場合に発生します。このような場合の答えは、インデックスを再構築または削除して再作成し、削除ステートメントを再度発行することです。

于 2020-08-03T14:31:44.770 に答える
0

上記のAndomarの回答の拡張として、最初の700,000,000レコード(約12億)が非常に高速に処理され、1秒あたり25,000レコードのチャンクが(おおよそ)処理されるシナリオがありました。しかし、その後、25,000のバッチを実行するのに15分かかり始めます。チャンクサイズを5,000レコードに減らしたところ、以前の速度に戻りました。到達した内部しきい値はわかりませんが、修正はレコード数を減らし、さらに速度を回復することでした。

于 2020-10-12T19:20:23.183 に答える
-10

CMDを開き、このコマンドを実行します

NET STOP MSSQLSERVER
NET START MSSQLSERVER

これにより、SQLServerインスタンスが再起動します。削除コマンドの後で再実行してみてください

このコマンドはバッチスクリプトに含まれており、このような問題が発生した場合は時々実行します。通常のPCの再起動は同じではないため、SQLサーバーで問題が発生した場合は、インスタンスを再起動するのが最も効果的な方法です。

于 2018-02-05T03:52:39.983 に答える