Оптимизация группы по кубу на SQL сервере - PullRequest
2 голосов
/ 04 мая 2020

Я хотел бы сделать GROUP BY CUBE из таблицы с 9 столбцами и более 107 миллионами строк. Вот пример моего кода:

 select     id
            ,case when grouping(cod_01)    = 0 then cod_01    else 0   end cod_01
            ,case when grouping(cod_02)     = 0 then cod_02     else 0   end cod_02
            ,case when grouping(cod_03)        = 0 then cod_03        else 0   end cod_03
            ,case when grouping(cod_04)   = 0 then cod_04   else 0   end cod_04
            ,case when grouping(cod_05) = 0 then cod_05 else 0   end cod_05
            ,case when grouping(input)    = 0 then input    else '0' end cod_input
            ,date
            ,historical
            ,COUNT(distinct pp) value
     from tmp.test
     where final_state in ('A','B')
     group by id
              ,cod_01
              ,cod_02
              ,cod_03
              ,cod_04
              ,cod_05
              ,input
              ,date 
              ,historical
               with cube 
     having GROUPING(id) = 0
            and GROUPING(cod_02) = 0
            and GROUPING(cod_03) = 0
            and GROUPING(date) = 0
            and GROUPING(historical) = 0

Это выполняется на SQL Сервер.

Для строк 10 КБ это занимает 7 секунд, но когда я увеличиваю количество строк до на 107 миллионов это заняло более 24 часов.

Как я могу улучшить свое предложение? Есть ли лучший способ сделать это?

1 Ответ

1 голос
/ 04 мая 2020

Помимо чего-то очевидного, например добавления индекса для столбца final_state (если он достаточно избирателен) или даже создания покрывающего индекса (тяжелого для хранения и снижающего производительность вставки / обновления), вы можете использовать Группировка наборов вместо куба + имея.

Он будет агрегировать данные по тем комбинациям столбцов, которые вам действительно нужны, вместо того, чтобы сначала вычислять все возможные комбинации с помощью Cube, а затем фильтровать их с помощью Have. Это может быть быстрее, но если результат этого запроса также содержит десятки миллионов строк, не ожидайте фейерверков.

Я проверил это на своем сервере (MS SQL 2012), и оказалось, что запрос с Cube + выполнил 6 отдельных сканирований индекса, а затем сцепил потоки, а запрос с групповыми наборами, который дает тот же результат выполнил только одно сканирование и был в несколько раз быстрее.

...