简单的删除,但是复杂的执行计划


9

当我运行此删除时:

DELETE FROM ETLHeaders WHERE ETLHeaderID < 32465870

...它删除39,157行。它应该很简单,因为它是在ETLHeaderID上删除的,而ETLHeaderID是聚簇索引和主键。但是(根据执行计划)它似乎达到361,190行并使用其他索引。该表确实具有XML数据类型的字段(以防影响此DELETE)。

有任何想法为何以及如何加快此DELETE?

这里的执行计划: http ://sharetext.org/qwDY这里的表模式:http : //sharetext.org/Vl9j

谢谢

Answers:


10

该计划的顶层与从基表(聚集索引)中删除行以及维护四个非聚集索引有关。在处理聚簇索引删除的同时,逐行维护其中两个索引。这些是下面以绿色突出显示的“ +2非聚集索引”。

对于其他两个非聚集索引,优化器已决定最好将这些索引的键保存到tempdb工作表(Eager后台处理程序)中,然后播放该后台处理两次,并按索引键进行排序以促进顺序访问模式。

定期维护索引

最后的操作顺序与维护主xml索引和辅助索引有关,这些索引未包含在DDL脚本中:

XML索引维护

在这方面没有太多要做。非聚集索引和xml索引必须与基表中的数据保持同步。维护此类索引的成本是您在表上创建额外索引时要权衡的一部分。

也就是说,xml索引特别成问题。对于这种情况,优化器很难准确评估多少行将符合条件。实际上,它疯狂地高估了xml索引,导致为此查询授予了将近12GB的内存(尽管在运行时仅使用了28MB):

估计的行数

您可以考虑以较小的批次执行删除操作,以期减少过多的内存授予的影响。

您也可以在不进行排序的情况下测试计划的性能OPTION (QUERYTRACEON 8795)。这是一个未记录的跟踪标志,因此您只能在开发或测试系统上尝试使用它,而绝不能在生产中使用它。如果生成的计划要快得多,则可以捕获计划XML并将其用于为生产查询创建计划指南


3

您走在正确的道路上-XML索引就是问题所在。显然,有一个主索引和一个辅助XML索引。

对基表(ETLHeaders)执行DELETE时,也必须从该表的每个索引中删除数据。这种开销可能非常大,尤其是对于XML索引而言。

导致持续时间较长的索引是辅助XML索引[XML_IX_ETLHeaders_Property]。“关系表”中的39,157行引用主XML索引[XML_IX_ETLHeaders]中的361,190行。并且需要对那些361k行进行排序,以便能够用来删除二级索引。并且这种排序操作导致查询的持续时间长。(请注意,两个xml索引的索引统计信息似乎相去甚远:主xml索引的361k行的实际数据大小为160MB,而估计的数据大小几乎为4TB(是,4 TerraByte!)) 。

我看到加快此查询速度的唯一选择是消除辅助XML索引。根据数据,将XML数据切入关系表可能是一个更好的选择。

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.