Список или объединение в оконной функции SQL - PullRequest
4 голосов
/ 30 сентября 2019

(относительно новый для SQL) член моей команды работал над написанием SQL-запроса, в котором использовалась оконная функция. При просмотре я заметил, что они структурировали свою оконную функцию следующим образом:

COUNT(*) OVER(PARTITION BY Part1+Part2) AS A

. Я немедленно сделал замечание обратной связи, чтобы сказать, что это должно быть так:

COUNT(*) OVER(PARTITION BY Part1, Part2) AS A

И Part1, и Part2nvarchars.

Затем я сделал паузу, чтобы подумать, и я не мог понять , почему это было бы неправильно. Насколько я вижу, это на самом деле даст идентичные результаты (это так). Фактический план выполнения практически идентичен, за исключением дополнительного шага Compute Scalar после первоначального сканирования таблицы по первому запросу (это 0% от стоимости запроса). Статистика ввода / вывода показывает, что в первой версии меньше логических операций чтения (от 12 665 до 12 670).

Так есть ли польза / ущерб в использовании любой из форм, помимо соглашений о кодировании? Является ли это случаем, что это работает нормально в этом случае, но при определенных обстоятельствах может привести к противоречивым результатам?

Ответы [ 2 ]

5 голосов
/ 30 сентября 2019

Оба выражения допустимы, но они не делают одно и то же.

Рассмотрим следующие данные:

Part1    Part2
AB       C
A        BC

При объединении строк с PARTITION BY Part1+Part2 обе записи попадают в одну и ту жеразделение, тогда как при использовании PARTITION BY Part1, Part2 они будут принадлежать разным разделам.

Таким образом, вопрос на самом деле сводится к следующему: каковы правильные критерии разделения для вашего варианта использования? Обычно, если вы не делаете что-то необычное, вы хотите PARTITION BY Part1, Part2. Но на самом деле на это нужно ответить с функциональной точки зрения, исходя из вашего реального варианта использования.

3 голосов
/ 30 сентября 2019

Выражение PARTITION - это как раз выражение. Таким образом, вы можете поместить туда практически любую форму выражения и использовать это значение для разбиения строк.

С точки зрения противоречивых результатов вы столкнетесь с проблемой, если у вас будет такой случай:

Part1    Part2    Part1 + Part2
'yummy'  'sushi'  'yummysushi'
'yumm'   'ysushi' 'yummysushi'

Обе строки будут считаться частью одного раздела, даже если столбцыимеют разные значения.

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

Лучше всего использовать второй указанный вами случай (Part1, Part2).

...