delete from a A where a.ID = 132.
表A包含大约5000条记录,A.ID是表A中的主键。但是删除需要很长时间。有时它也会超时。该表包含三个索引,并由三个外键引用。谁能解释我为什么即使我们基于主键删除它也需要很长时间。请告诉我一些优化这个问题的方法......?
delete from a A where a.ID = 132.
表A包含大约5000条记录,A.ID是表A中的主键。但是删除需要很长时间。有时它也会超时。该表包含三个索引,并由三个外键引用。谁能解释我为什么即使我们基于主键删除它也需要很长时间。请告诉我一些优化这个问题的方法......?
可能的原因:
1)级联删除操作
2) 触发器
3)您的主键列的类型不是整数,从而强制对每个 pk 值进行类型转换以进行比较。这需要全表扫描。
4)您的查询真的像您在问题中发布的那样以点结尾吗?如果是这样,该数字可能会被认为是浮点数而不是整数,从而导致类似于 3 的类型转换)
5)您的删除查询正在等待其他一些慢查询来释放锁
显然它不应该花费很长时间。但是,这里没有足够的信息来找出确切的原因。不过,我可以告诉你,你应该专注于外键。
如果它们施加来自其他更大的表的约束,它们可能会减慢速度。您可能还会发现您的超时是由于防止删除的完整性检查造成的(那么问题是为什么您没有收到异常而不是超时)。
我的下一步是删除外键,然后检查性能。然后一次添加每一个,并随时检查性能。
其他操作(例如插入、选择、更新)是否需要很长时间?
第一个想法:外键索引?
第二个想法:触发射击?
尝试更新统计信息。5000 行没什么大不了的。如果您定期执行此操作,您还应该安排对该表的维护(即重新构建索引、更新统计信息等)
正如其他人所观察到的,可能的嫌疑人是外键。
首先是因为如果从属表又被其他表引用,而其他表又可能被引用,等等,ON DELETE CASCADE 可以聚集势头。
其次,因为其他用户可能对需要删除的行有锁。这是超时的最可能原因。这将如何工作将取决于您的数据库的风格和版本。例如,旧版本的 Oracle (<=8.0) 需要锁定整个依赖表,除非外键列被索引。