sql server delete被索引大幅减速

Kev*_*vin 5 sql-server optimization stored-procedures sql-delete

我正在运行一个归档脚本,它根据输入的日期从大型(~50m记录DB)中删除行.日期字段是表上的聚集索引,因此我正在应用我的条件语句.

我在while循环中运行此删除,尝试批量处理1000到100,000条记录.无论批量大小,它都非常缓慢; 像10,000条记录一样被删除一分钟.查看执行计划,"索引删除"花费了大量时间.表中大约有15个字段,其中大约有10个字段具有某种索引.有什么方法可以解决这个问题吗?我甚至不确定为什么每个索引删除都需要这么长时间,有人可以了解到这里发生了什么?这是我执行计划的一个示例:

alt text http://img94.imageshack.us/img94/1006/indexdelete.png

(序列指向删除命令)

这个数据库是实时的,并且经常被插入,这就是为什么我对使用修剪大小的复制和截断方法犹豫不决.我在这里还有其他选择吗?

Rem*_*anu 6

从聚簇索引+ 5个非聚类索引中删除10k记录应该定义为1分钟.听起来你有一个非常慢的IO子系统.有什么价值:

  • 平均.磁盘秒/写
  • 平均.磁盘秒/读
  • 平均.磁盘写入队列长度
  • 平均.磁盘读取队列长度

在操作中涉及的每个驱动器上(包括Log的!).如果将索引放在单独的文件组中并将每个文件组分配给自己的LUN或自己的磁盘,则可以确定哪些索引更有问题.此外,日志刷新可能是一个主要瓶颈.SQL Server在这里没有太多控制权,一切都在你手中如何加快速度.该时间不用于CPU周期,等待IO完成,您需要为您需要的负载校准IO子系统.

要减少IO负载,您应该考虑使索引更窄.首先,确保聚集索引是最有效的.然后,确保非聚簇索引不包括繁琐的未使用的大列(我已经看到了......).通过启用页面压缩可以获得主要收益.最后,检查sys.dm_db_index_usage_stats中的索引使用情况统计信息,看看是否有任何索引对ax有好处.

如果无法大幅降低IO负载,则应尝试拆分它.将文件组添加到数据库,在单独的文件组上移动大索引,将文件组放在单独的IO路径(不同的轴)上.

对于将来的常规删除操作,最好的替代方法是使用分区切换,使所有索引与聚簇索引分区对齐,当时间到期时,只需删除最后一个分区以进行快速删除.

  • 你是否如此自信,甚至没有去衡量? (8认同)

Red*_*ter 1

更多的解决方法,但是您可以IsDeleted向表添加一个标志并将其更新而1不是删除行吗?您将需要修改您的SELECTsUPDATEs才能使用此标志。

然后,您可以安排在非工作时间删除或归档这些记录。