画一个简单的表结构:
Table1 Table2
---------- ----------
ID<-------| ID
Name |-->Table1ID
Name
Table1
有几百万行(例如 350 万行)。我通过主键发出删除:
DELETE FROM Table1 WHERE ID = 100;
中没有行Table2
引用Table1
with ID = 100
,因此删除操作不会违反任何外键约束。
您预计删除需要多长时间?大约几毫秒?几百毫秒?一秒或更长时间?几秒钟?等等,假设机器没有陷入困境并且可以轻松处理请求。
现在,我遇到这样的情况,像这样的删除大约需要 700 毫秒。对我来说,这似乎太慢了。我很好奇我是否偏离了基地,或者其他人是否认为这太慢了,以及有助于加快速度的建议!
下面是实际的执行计划:
(此处的 XML 执行计划:http://pastebin.com/q9hSMLi3 http://pastebin.com/q9hSMLi3)
聚集索引删除(81%)命中聚集PK、非聚集唯一索引、非聚集非唯一索引。
问题是用于验证外键的聚集索引扫描。
当删除成功并且没有匹配的记录会导致违规时,则所有table2
需要扫描。该表有 1,117,190 行,因此这是一项昂贵的操作,绝对可以从索引中受益。
执行计划中显示的 10% 这个数字只是基于某些建模假设的估计。
整个计划的成本为0.0369164
表 2 的扫描成本为0.0036199
以及剩余的所有其他内容0.0332965
。但请注意,对于聚集索引扫描运算符,估计的 CPU 成本为1.22907
预计 IO 成本为10.7142
(总计11.94327
not 0.0369164
).
造成这种差异的原因是扫描是在反半连接运算符下进行的,并且一旦找到匹配的行,扫描就会停止。估计的子树成本在建模假设下按比例缩小,即这将在仅扫描表的一小部分之后发生。
如果没有 FK 违规并且删除成功,则需要扫描整个表,因此使用未按比例缩小的数字会提供更多信息。
如果使用以下公式重新计算百分比11.94327
代表实际发生的完整扫描的操作员的成本,则该扫描操作员显示为计划成本的 99.7%(11.94327 / (11.94327 + 0.0332965)
).
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)