Простое УДАЛЕНИЕ, но сложный план выполнения

9

Когда я запускаю это удаление:

DELETE FROM ETLHeaders WHERE ETLHeaderID < 32465870

... удаляет 39 157 строк. Это должно быть просто, потому что это удаление по ETLHeaderID, который является кластеризованным индексом и первичным ключом. Но (согласно плану выполнения) кажется, что он набирает 361 190 строк и использует другие индексы. В таблице есть поле с типом данных XML (в случае, если это влияет на DELETE).

Есть идеи, почему и как я могу ускорить это УДАЛЕНИЕ?

План выполнения здесь: http://sharetext.org/qwDY Схема таблицы здесь: http://sharetext.org/Vl9j

Спасибо

Крейг Х.Б.
источник

Ответы:

10

Верхние уровни плана связаны с удалением строк из базовой таблицы (кластеризованный индекс) и поддержкой четырех некластеризованных индексов. Два из этих индексов поддерживаются построчно, в то же время обрабатываются удаления кластеризованных индексов. Это «+2 некластеризованных индекса», выделенных зеленым цветом ниже.

Для двух других некластеризованных индексов оптимизатор решил, что лучше всего сохранить ключи этих индексов на рабочем столе tempdb (Eager Spool), а затем дважды воспроизвести спул, отсортировав его по ключам индекса, чтобы обеспечить последовательный шаблон доступа.

Регулярное обслуживание индекса

Последняя последовательность операций связана с поддержанием первичных и вторичных xmlиндексов, которые не были включены в ваш сценарий DDL:

Обслуживание индекса XML

С этим ничего не поделаешь. Некластеризованные индексы и xmlиндексы должны синхронизироваться с данными в базовой таблице. Стоимость обслуживания таких индексов является частью компромисса, который вы делаете при создании дополнительных индексов для таблицы.

Тем не менее, xmlиндексы являются особенно проблематичными. Оптимизатору очень сложно точно оценить, сколько строк будет соответствовать этой ситуации. Фактически, он xmlсильно переоценивает индекс, в результате чего для этого запроса выделяется почти 12 ГБ памяти (хотя во время выполнения используется только 28 МБ):

Расчетное количество строк

Вы могли бы рассмотреть возможность удаления в меньших пакетах, надеясь уменьшить влияние чрезмерного предоставления памяти.

Вы также можете проверить производительность плана без использования сортировок OPTION (QUERYTRACEON 8795). Это недокументированный флаг трассировки, поэтому его следует использовать только в системе разработки или тестирования, а не в производстве. Если результирующий план намного быстрее, вы можете захватить XML плана и использовать его для создания руководства по плану для производственного запроса.

Пол Уайт 9
источник
3

Вы на правильном пути - проблема с индексом XML. Очевидно, есть первичный, а также вторичный XML-индекс.

При выполнении DELETE для базовой таблицы (ETLHeaders) данные также должны быть удалены из каждого индекса этой таблицы. Эти издержки могут быть значительными, особенно для XML-индексов.

Индексом, вызывающим большую продолжительность, является вторичный XML-индекс [XML_IX_ETLHeaders_Property]. 39,157 строк в вашей «реляционной таблице» ссылаются на 361,190 строк в первичном индексе XML [XML_IX_ETLHeaders]. И эти 361 тыс. Строк необходимо отсортировать, чтобы можно было использовать для удаления вторичного индекса. И эта операция сортировки вызывает большую продолжительность запроса. (Как примечание, статистика индексов обоих индексов xml, похоже, далека от действительности: фактический размер данных 361 тыс. Строк первичного индекса xml составляет 160 МБ, тогда как предполагаемый размер данных составляет почти 4 ТБ (да, 4 TerraByte !!)) ,

Единственный вариант, который я вижу для ускорения этого запроса, - это исключить вторичный XML-индекс. В зависимости от данных может быть лучшим вариантом измельчить данные XML в реляционную таблицу.

Lmu92
источник