Новость из категории: Информация

SQL Server 2016: агрегатный оконный оператор пакетного типа | RANGE с разделителями UNBOUNDED и CURRENT ROW. Продолжение

SQL Server 2016: агрегатный оконный оператор пакетного типа | RANGE с разделителями UNBOUNDED и CURRENT ROW. Продолжение

В рассматриваемом нами плане есть скрытая проблема, имеющая отношение к производительности. Всякий раз, когда вы выбираете вариант RANG E, SQL Server использует дисковый буфер для оператора Window Spool (в отличие от размещаемого в оперативной памяти буфера, который система использует в варианте ROWS в ускоренном режиме). Дисковый буфер, в сущности, представляет собой рабочую таблицу базы данных tempdb со всеми обычными непроизводительными затратами, связанными с подсистемой ввода-вывода и блокировками. Следовательно, расчет по варианту RANGE может занять на порядок больше времени, чем аналогичный расчет по варианту ROWS, даже в том случае, когда упорядочение уникально. Опять же, об этом обстоятельстве вы не можете узнать, просматривая план. Вот статистические данные, полученные мною при выполнении данного запроса: продолжительность— 221 секунда, процессор — 204 секунды, логические операции считывания — 104К, записи — 31К. Отмечу, что продолжительность выполнения данного запроса на порядок больше, чем у запроса Query 1. Кроме того, должен обратить ваше внимание на чрезмерное количество логических операций считывания. Если перед выполнением запросов вы активируете настройку STATISTICS 10, то на выходе получите запись для буфера с именем worktable. В этой записи количество логических операций считывания будет равно нулю при использовании варианта ROWS и составлять весьма большое число в случае применения варианта RANGE. Это один из способов убедиться, что вы имеете дело с дисковым буфером. Другой способ — запустить сеанс Extended Events с событием window_ spool_ondisk_warning.

SQL Server 2016: агрегатный оконный оператор пакетного типа | RANGE с разделителями UNBOUNDED и CURRENT ROW. Продолжение
Упрощенный запрос, эквивалентный запросу Query 4

Ситуация усугубляется тем, что, если вы опустите предложение с блоком фрейма окна, стандартный SQL определит, что спецификация RANGE UNBOUNDED PRECEDING должна применяться по умолчанию. Таким образом, запрос в коде выше семантически эквивалентен запросу Query 4 с теми же низкими показателями быстродействия.



Не могу и подсчитать, как часто я видел людей, использующих RANGE, даже не подозревая об этом (себя я тоже отношу к их числу). Особенно трудно обращать на это внимание в случаях, когда вы испытываете собственный код с использованием небольшого набора тестовых данных и упорядочение уникально в рамках данного раздела, как в нашем примере. Только вдумайтесь, как много систем используют подобный код с запросами, выполняемыми на порядок медленнее, чем должно. И вот оказывается, что оператор Window Aggregate решает и эту проблему. По существу, оп оптимизирует ROWS и RANGE аналогичным образом.

SQL Server 2016: агрегатный оконный оператор пакетного типа | RANGE с разделителями UNBOUNDED и CURRENT ROW. Продолжение
Запрос Query 5

Показанный в коде выше запрос (назовем его Query 5) демонстрирует использование пакетного режима при обработке данных в представлении columnstore.

SQL Server 2016: агрегатный оконный оператор пакетного типа | RANGE с разделителями UNBOUNDED и CURRENT ROW. Продолжение
План выполнения запроса Query 2 (ROWS, пакетный режим обработки данных в представлении columnstore)

Этот план напоминает приведенный на рисунке выше план для запроса Query 2. Вот какие статистические данные я получил по итогам выполнения данного запроса: продолжительность — 9 секунд, процессор — 21 секунда, логические операции считывания — 6 К, записи — 0. Запрос, приведенный в коде ниже (я буду называть его Query 6), демонстрирует использование пакетного режима обработки данных в представлении rowstore.

SQL Server 2016: агрегатный оконный оператор пакетного типа | RANGE с разделителями UNBOUNDED и CURRENT ROW. Продолжение
Запрос Query 6

SQL Server 2016: агрегатный оконный оператор пакетного типа | RANGE с разделителями UNBOUNDED и CURRENT ROW. Продолжение
План выполнения запроса Query 3 (ROWS, пакетная обработка данных rowstore)

Этот план аналогичен плану выполнения запроса Query 3 (см. рисунок выше). Вот какие статистические данные я получил по итогам его выполнения: продолжительность — 7 секунд, процессор — 7 секунд, логические операции считывания — 31 К, записи — 0.

SQL Server 2016: агрегатный оконный оператор пакетного типа | RANGE с разделителями UNBOUNDED и CURRENT ROW. Продолжение
Характеристики выполнения агрегирующих функций с разделителями UNBOUNDED и CURRENT ROW

Характеристики выполнения запросов с первого по шестой представлены на рисунке выше.


<<К началу статьи

Рейтинг статьи

Оценка
0/5
голосов: 0
Ваша оценка статье по пятибальной шкале:
 
 
   

Поделиться

Похожие новости

Комментарии

^ Наверх