|
|
|||||||||||||||||||||||||||||
|
Performance issues with PIVOTИсточник: habrahabr AlanDenton
В современных информационных системах, процесс принятие решения, зачастую, строится на основании консолидированной информации. На практике же, при разработке бизнес-логики, оперирующей подобной информацией, очень часто приходится преобразовать строки в столбцы.
В синтаксисе T-SQL для выполнения подобного преобразования предусмотрена отдельная конструкция PIVOT . Стоит заметить, что в SQL Server 2000 поддержки конструкции PIVOT еще не было, поэтому аналогичные задачи решались через множественные CASE WHEN. Собственно, почему я упомянул о CASE WHEN , если есть PIVOT ? Ведь, по определению, PIVOT более элегантная конструкция и, соответственно, должна быть более эффективной. Проверим это на практике…
И заполним ее тестовыми данными:
Далее напишем PIVOT запрос, который будет возвращать количество выходов по каждому сотруднику в разрезе дней:
При выполнении запроса мы получим следующий план и время выполнения:
SQL Server Execution Times: На плане можно увидеть операторы Sort и Hash Match . Их эффективная работа очень сильно зависит от размера входящих данных и доступного объема физической памяти, чтобы эти самые данные обработать. При невозможности выделить требуемый объем памяти, обработка результатов будет происходить в базе tempdb (восклицательный знак) - это может приводить к ощутимой нагрузке на дисковую подсистему и увеличению времени выполнения запроса:
SQL Server Execution Times: Посмотрим как ведет себя аналогичная по функциональности конструкция из CASE WHEN условий:
При выполнении мы получим более простой план. При этом время выполнения будет не слишком отличатся от PIVOT (разумеется в рамках погрешности):
SQL Server Execution Times: В условиях нехватки памяти мы получим следующие результаты:
SQL Server Execution Times: Из полученных данных можно сделать небольшое наблюдение - при агрегации данных по одному столбцу явное преимущество за конструкцией PIVOT . Даже в ситуации, когда наблюдается нехватка памяти на обработку результатов. Теперь посмотрим как себя ведут данные примеры при увеличении чиста столбцов по которым идет агрегация. 1. Группировка в разрезе: сотрудник + год:
SQL Server Execution Times:
SQL Server Execution Times: Если сравнить планы, то можно заметить, что операция Hash Match более затратна при использовании PIVOT , но время выполнения говорит об обратном. 2. Группировка в разрезе: сотрудник + год + месяц
SQL Server Execution Times:
SQL Server Execution Times: Собственно говоря, ситуация повторяется - SQL Server оценивает PIVOT конструкцию как более затратную. Но время выполнения опять все ставит на свои места. Из этого можно сделать небольшие выводы: в преобладающем большинстве ситуаций с помощью конструкции PIVOT можно быстрее выполнить преобразования столбцов в строки. Небольшое замечание при этом следующее: с увеличением числа столбцов, по которым идет агрегация, разница во времени выполнения между PIVOT и CASE WHEN будет сокращаться и в определенный момент будет в рамках погрешности измерений. PS: Все эксперименты проводились на SQL Server 2012 SP1 (11.00.3128) . Ссылки по теме
|
|