DELETE操作时的性能问题

时间:2017-06-06 06:27:21

标签: sql sql-server sql-server-2008

我有一个简单的删除语句:

DELETE FROM MY_TABLE WHERE ID='Something'

这只会删除该ID的一条记录,这个记录花费的时间超过一分钟,因为在另一个拥有大约4千万条记录的表上创建的外键引用了MY_TABLE,并且DELETE操作检查是否存在此ID在那张大桌子里。

一种方法是删除/重新创建此外键,但此DELETE操作由应用程序用户执行,我不能只是动态地删除/重新创建此FK,除非它可能是非工作时间操作

有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

因此,您可以参考一个优秀的SO问题 SQL delete performance

除了有关像

这样的问题的建议
  

可能的原因:

     

1)级联删除操作

     

2)触发器

     

3)主键列的类型不是a   整数,从而强制对每个pk值进行类型转换   比较。这需要全表扫描。

     

4)你的查询是否真的以你在帖子中发布的点结尾   题?如果是这样,该数字可能被认为是浮点数   数字而不是整数,从而导致类型转换   类似于3)

     

5)你的删除查询正在等待其他一些慢查询释放a   锁定

<强>重要的

  1. 我们一定要研究触发器。如果有的话,你应该尝试取消触发器。
  2. 还要尝试查看其他大表中FK上是否有索引。
  3. 看看您是否可以将查询转换为CASCADE删除以从大表中删除,然后从MY_TABLE中删除,如下面的查询

    DELETE FROM LARGE_TABLE WHERE LT.FK IN (SELECT PK FROM MY_TABLE WHERE ID='Something') GO DELETE FROM MY_TABLE WHERE ID='Something'

    另请参阅LARGE_TABLE上第一次查询的效果计划。

  4. 您应尝试使用WHERE ID='Something'INT键操作替换WHERE anotherID=34。基本上不是在WHERE中使用字符串,而是尝试使用整数进行删除。很难相信varchar中的ID列。您应该在MY_Table中有一个主键聚簇索引列,并在WHERE子句中使用此键。

  5. 提高性能的另一种方法是删除表之间的FK约束。您可以随时定期从LARGE_TABLE删除垃圾,然后进行索引重建。

  6. 另一种更简单的方法是在这些表之间引入映射表。比如说存在一个名为Map_My_Table_Large_Table的表,它保留了以下列(来自My_Table的FK列,来自Large_Table的FK列)。您可以将CASCADE删除更改为此表。