Почему оптимизатор запросов использует сортировку после объединения слиянием? - PullRequest
0 голосов
/ 11 октября 2018

Рассмотрим этот запрос:

select
    map,line,pda,item,qty,qty_gift,pricelist,price,linevalue,vat,
    vat_value,disc_perc,disc_value,dt_disc_value,netvalue,imp_qty,
    imp_value,exp_qty,exp_value,price1,price2,price3,price4,
    justification,notes
  from appnameV2_Developer.dbo.pt
  where exists (select 1 from [dbo].[dt] dt 
                where pt.map=dt.map and dt.pda=pt.pda and dt.canceled=0)
except
select 
    map,line,pda,item,qty,qty_gift,pricelist,price,linevalue,vat,
    vat_value,disc_perc,disc_value,dt_disc_value,netvalue,imp_qty,
    imp_value,exp_qty,exp_value,price1,price2,price3,price4,
    justification,notes
  from appnameV2_Developer_reporting.dbo.pt

Я сделал это, чтобы убедиться, что в одной и той же таблице (pt) нет различий между базой данных издателя репликации (appnameV2_Developer) и базой данных подписчиков (appnameV2_Developer_reporting).Конкретная статья репликации имеет полусоединение на dt.

dt - это таблица заголовка транзакции с PK (map, pda)

pt - это таблица с подробностями транзакции с PK (map, pda, line)

Вот план выполнения

Итак, у нас есть соединение с правым полу-объединением.Я ожидаю, что его результат будет упорядочен (map, pda, line).Но затем вызывается оператор сортировки (map, pda, line).

Почему происходит такая сортировка (или, точнее: почему данные еще не отсортированы по этой точке)?В оптимизаторе запросов отсутствует логика: «при объединении слиянием его выходные данные (все еще) сортируются по предикатам объединения»?Я что-то пропустил?

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Результаты первого слияния будут отсортированы по map, pda, line.Однако вы сами упомянули предикаты объединения, и предикаты объединения для этого первого слияния основаны только на map, pda (они являются предикатами из условия exists, за исключением того, что один cancelled был перенесен в индекссканирование).Все, что для первого слияния required было введено, отсортировано по map и pda, и, таким образом, это единственный порядок сортировки, гарантированный для этих данных, что касается остальной части запроса.

Но, как мы знаем, выходные данные этого первого слияния были фактически получены из входных данных, которые были дополнительно отсортированы по line.Похоже, что оптимизатор в настоящее время не может определить это обстоятельство.Возможно, что порядок оптимизации означает, что вряд ли когда-либо будет распознана такая ситуация.Поэтому в настоящее время вводится дополнительная сортировка.

0 голосов
/ 11 октября 2018

Поскольку было решено использовать «Объединение слиянием», чтобы выполнить предложение EXCEPT.Чтобы выполнить объединение слиянием, оба набора данных должны иметь одинаковый порядок.

Дело в том, что внутреннее объединение слиянием (до ИСКЛЮЧЕНИЯ) основано на таблице dt, а не на pt.Поэтому результирующие строки не будут иметь тот же порядок, что и другая сторона EXCEPT, основанная на pt.

Почему SQL Server делает это?Не ясно.Я бы сделал это по-другому.Возможно статистика не обновляется.Возможно, есть небольшое количество строк, где стратегия не имеет большого значения.

...