SQL Serverでの低速なDELETEに対して要求された説明


8

SQL Serverの削除動作に関する追加の洞察/推論を取得したいと思います。1800 GBを超えるかなり大きなデータベースがあります。

数百万行の非常に浅いテーブル(少数の整数列のみ)があります。これらの浅いテーブルから10,000の行を削除する場合、削除クエリは一般に非常に高速です(多くても数秒)。

また、image平均100 KBの画像を保存するタイプのフィールドを持つテーブルもあります。このテーブルから数千行しか削除しない場合、1分以上かかります。

違いは明らかですが(サイズの点ではるかに多くのデータが削除されます)、SQL Server内で何が起こるかについてもっと知りたいと思っています。後者の削除が非常に遅くなることをよりよく理解できるように。

誰かが光を当ててくれますか?


そのようなことに興味があり、ソースに近いものから聞きたい場合は、SQL Serverの内部に関する本があります。
stakx 14

私の疑いは、イメージの削除が偶然に大量のランダムIOを生成するか、何かがブロックすることです。数千行を削除しても、CPU使用率が1分間になることはありません。
usr

回答:


10

サイズ的にははるかに多くのデータが削除されます

100kb imageblobの削除は、実際にはデータのサイズ操作ではありません。blobは割り当て解除され、削除されず、フルイメージロギングはありません。これは簡単にテストできます。

create database blob
go

use blob
go

create table t (id int not null identity(1,1), blob image)
go

insert into t (blob) values (
  replicate(
    cast(0x000102030405060708090a0b0c0d0e0f as varbinary(max)), 
    100*1024/16))
go 10

alter database blob set recovery full
go

backup database blob to disk='nul:'
go

delete from t where id = 3
go

select * from fn_dblog(null, null)
go

表示されるログレコードは次のようになります。

00000026:0000008e:0001  LOP_BEGIN_XACT  LCX_NULL    0000:00000304   0x0000  76  124
00000026:0000008e:0002  LOP_LOCK_XACT   LCX_NULL    0000:00000304   0x0000  24  56
00000026:0000008e:0003  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:0004  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:0005  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:0006  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:0007  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:0008  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:0009  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:000a  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:000b  LOP_MODIFY_ROW  LCX_PFS     0000:00000304   0x0000  62  92
00000026:0000008e:000c  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
...    
00000026:0000008e:0022  LOP_HOBT_DELTA  LCX_NULL    0000:00000304   0x0000  64  64
00000026:0000008e:0023  LOP_DELETE_ROWS LCX_TEXT_MIX    0000:00000304   0x0000  62  172
00000026:0000008e:0024  LOP_DELETE_ROWS LCX_HEAP    0000:00000304   0x0000  62  120
00000026:0000008e:0025  LOP_COMMIT_XACT LCX_NULL    0000:00000304   0x0000  80  84

ご覧のとおり、列を含む行の+102400バイトのデータを持つ「DELETE」レコードはありませんimage。一連の割り当て解除(PFS / IAM / GAM操作)と単純な行の削除(私の場合のヒープは、IDをPKとして宣言することを覚えていれば、Bツリーと非常によく似ています...)があります。詳細については、SQL Serverログの読み取りと解釈の方法を参照してください。

どちらが元の質問を開いたままにします:なぜ一方の削除が他方より遅いのですか?SQL Serverのパフォーマンスを分析する方法を読むことをお勧めします。説明されている方法に従って、特定のステートメントの待機をキャプチャし、原因を確認します。個別クエリ実行の分析、特に個別クエリ実行待ち時間の分析に関する部分を参照してください。あなたが測定した後にのみ、私たちは謎に答えることができます。多くの要因が考えられます。blobテーブルでの同時読み取りによるブロッキングの増加、1つのテーブルでDELETE候補行を見つけるためのインデックスの欠落、実行中のトリガーなど。リンクされた方法は、原因を特定するのに役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.