提高SQL Server的删除速度


12

我们拥有庞大的生产数据库,其大小约为300GB。有什么方法可以提高删除查询的性能?目前,删除速度为每分钟1-10k,这对我们来说非常慢。


2
每分钟1000行听起来非常慢。您遇到封锁了吗?还是选择行也一样慢,这表明需要索引?
James Z

可能您必须创建索引来覆盖您的删除条件。
登2015年

6
没有足够的细节来提供答案。您执行哪个查询?您在所涉及的条件列上是否有索引(如果有)?您有删除触发器吗?...
塞巴斯蒂安·塞夫林

3
您是否要一次删除十亿行?自动增长后,您有可能在等待自动增长吗?(很有可能是您正在等待的日志活动,而不是实际的删除活动。)请参阅本文 ……
亚伦·伯特兰

3
也。有外键约束吗?请提供完整的表定义,查询和执行计划。
马丁·史密斯

Answers:


20

如果您试图在单个语句中删除大量行,则可能正在等待日志活动。这样你就可以:

  1. 确保您的日志大小合适,以免增长事件使您减速。使用默认值,您的日志可能从1MB开始,增长10%。增长事件非常昂贵,而且即使您记录了10 GB的删除操作,这不仅会影响现在的性能,而且还会破坏将来的性能(由于这会对VLF造成影响)。
  2. 如果要删除整个表,使用TRUNCATEDROP/ CREATE
  3. 如果要删除大部分表,请使用SELECT INTO将要保留的数据放入另一个表,然后将TRUNCATE,然后将一小部分移回。(或者只是删除旧表,重命名新表,然后重新应用约束/权限等。)
  4. 首先删除数据块,而不是一次删除所有数据,以最大程度地减少首次登录的影响。看到这篇文章。您还可以考虑暂时切换到简单恢复,因此您只需要CHECKPOINT清除日志而不是进行日志备份,但是您需要确保将其重新设置并进行新的完整备份以重新启动日志链。

+1,来自我的精彩文章。过去,这帮助我使开发人员在继续联系我们以了解日志文件的速度和增长时,了解删除操作。
KASQLDBA 2015年

此外,如果有任何不必要的索引,将其删除会提高删除速度。同样,如果删除所有或几乎所有数据,则首先删除所有索引,然后再创建它们可能会产生很好的影响。
托尼·欣克尔

3
@Tony删除索引也必须记录下来(创建索引时也要记录),因此可能只需要何时支付此费用即可。如果不进行测试,我不认为删除方案具有巨大的优势(就像插入/更新一样),除非您没有索引,否则将不保留。
亚伦·伯特兰

暂时禁用FK约束是否可以改善查询?
Lev Z

3

有一些提示,但是您使用的是哪个版本?是企业版吗?无论如何:

  1. 如果可以,请将事务日志移到更快的磁盘上
  2. 分析哪里。它将使用索引来标识要删除的记录吗?如果没有,您可以添加索引吗?
  3. 表格上是否有任何可删除的索引?如果是,请将其放下。
  4. 相对于此表,您有外键吗?这些确实会减慢您的删除速度。
  5. 如果您拥有企业版,而瓶颈是磁盘IO,则行级压缩可以为您提供一点帮助(或不,取决于您的数据)
  6. 您可以分区表吗?本地索引和分区删除可以更快。
  7. 通过活动监视器调查瓶颈所在。

添加详细信息,当您使用大型数据库时,没有一个有效的答案。


0

您应该尝试逐块删除它们,可能是在循环中删除,每次删除迭代都是它自己的事务,然后在每次循环迭代结束时清除日志。

另外,您将需要找到要用作块中值的数字以删除记录。它需要进行彻底的测试,如果可以先在UAT中测试块值,那就更好了。

关于如何继续,请参考将大删除操作分成多个块


0

如果大表具有递归外键,则删除操作可能会很慢。

如果是这样,找到合适的时间,禁用依赖服务,禁用递归外键,执行大量删除,然后再次还原外键。


这完全是我的情况。这是一个有点冒险禁用contraint,但是从1行/ seocnd删除跑到500 /秒
Jurion

0

再加一点...

  1. 尝试检查谓词上是否有索引,并查看统计信息。
  2. 如果要删除大量行,并且您也不想使用临时表选项。去tablock选择。
  3. 查看是否有任何触发器,特别是在删除触发器之后。

要获得更多帮助,请发布您正在使用的查询,表信息以及所有阻止信息。

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.