我有一个简单的删除语句:
DELETE FROM MY_TABLE WHERE ID='Something'
这只会删除该ID的一条记录,这个记录花费的时间超过一分钟,因为在另一个拥有大约4千万条记录的表上创建的外键引用了MY_TABLE
,并且DELETE操作检查是否存在此ID在那张大桌子里。
一种方法是删除/重新创建此外键,但此DELETE操作由应用程序用户执行,我不能只是动态地删除/重新创建此FK,除非它可能是非工作时间操作
有人可以帮忙吗?
答案 0 :(得分:0)
因此,您可以参考一个优秀的SO问题 SQL delete performance
除了有关像
这样的问题的建议可能的原因:
1)级联删除操作
2)触发器
3)主键列的类型不是a 整数,从而强制对每个pk值进行类型转换 比较。这需要全表扫描。
4)你的查询是否真的以你在帖子中发布的点结尾 题?如果是这样,该数字可能被认为是浮点数 数字而不是整数,从而导致类型转换 类似于3)
5)你的删除查询正在等待其他一些慢查询释放a 锁定
<强>重要的强>:
看看您是否可以将查询转换为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
上第一次查询的效果计划。
您应尝试使用WHERE ID='Something'
等INT
键操作替换WHERE anotherID=34
。基本上不是在WHERE中使用字符串,而是尝试使用整数进行删除。很难相信varchar中的ID
列。您应该在MY_Table
中有一个主键聚簇索引列,并在WHERE子句中使用此键。
提高性能的另一种方法是删除表之间的FK约束。您可以随时定期从LARGE_TABLE
删除垃圾,然后进行索引重建。
另一种更简单的方法是在这些表之间引入映射表。比如说存在一个名为Map_My_Table_Large_Table的表,它保留了以下列(来自My_Table的FK列,来自Large_Table的FK列)。您可以将CASCADE删除更改为此表。