请求使用SQL Server进行慢速DELETE的说明


8

我想对SQL Server删除行为获得一些额外的见解/理由。我们有一个相当大的数据库,超过1800 GB。

在其中有一些非常浅的表(只有几个整数列),具有数百万行。当我们从这些浅表中删除10,000行时,删除查询通常非常快(最多几秒钟)。

我们还有一个表,其中的类型字段image存储平均100 KB的图像。当我们仅从该表中删除几千行时,则需要一分钟多的时间。

尽管区别很明显(删除了更多的按大小分配的数据),但我还是渴望了解更多有关SQL Server内部发生的情况。这样我才能更好地理解后者的删除速度要慢得多。

谁能给我一些启示?


如果您对这种事情感兴趣,并且想听听接近源头的人的话,那么有一本关于SQL Server内部
stakx

我的怀疑是图像删除恰巧会产生大量随机IO,或者它们阻塞了某些东西。删除几千行不会以任何方式导致一分钟的CPU使用率过高。
usr 2014年

Answers:


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

如您所见,对于包含该image列的行,没有+102400字节数据的'DELETE'记录。有大量的释放(PFS / IAM / GAM操作)和简单的行删除(在我的情况下,如果我记得将ID声明为PK,则对于B-Tree看起来很相似)。有关更多详细信息,请参见如何阅读和解释SQL Server日志

留下了一个原始问题:为什么一个删除要比另一个慢?我建议您阅读如何分析SQL Server性能。请遵循所描述的方法来捕获等待特定声明的原因,然后查看原因。请参阅分析单个查询执行,特别是有关分析单个查询执行等待时间的部分。只有在您测量之后,我们才能回答这个谜语。可能有许多因素:由于并发读取blob表,缺少索引而无法在一个表上定位DELETE候选行,触发运行等导致更多阻塞。链接的方法将帮助您查明原因。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.