|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
Есть таблица: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35.
В таблице на данный момент 46 485 293 записей. Выполняю запрос: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
Запрос отрабатывает достаточно долго, около 3 минут. План во вложении и тут: Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
Версия сервера: Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64) Oct 19 2012 13:38:57 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1) Уважаемые участники форума, подскажите, каким образом сократить время выполнения запроса до приемлемого? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 11:59 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
индексированное представление не предлагать? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 12:10 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
Мистер Хенки, а как оно поможет? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 12:18 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
_ч_Мистер Хенки, а как оно поможет? все сведется к сканированию индекса представления, вместо агрегирования . Полагаю количество операций чтения уменьшится равно как и потребление процессорного времени, что должно привести к убыстрению запроса. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 12:29 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
_ч_, Действительный план лучше выкладывать файлом в формате xml/sqlplan. А что за значок там такой на хэш-джойне, не предупреждение о спилл, случайно? Как отличаются действительное число строк от оценок? Если отличаются, можно попробовать создать многоколоночную статистику: Код: sql 1.
Это поможет оптимизатору лучше оценить кардинальность группировки. Если кардинально изменить выполнение, то индексированное представление очень хороший вариант. Поможет тем, что серверу не нужно будет ничего считать, все будет уже посчитано в представлении и сохранено т.к. на нем будет индекс. Правда, разумеется, возрастут расходы на операции модификации, т.к. серверу придется поддерживать актуальность индекса представления. Насколько это критично - нужно смотреть по интенсивности изменения данных. Также такой запрос очень хорошо подходит для Columnstore индекса. Минус в том, что в текущей реализации он неизменяем (что фактически приводит к невозможности изменения таблицы), так что минусом будет необходимость продумывания стратегии обновления. Можно еще попробовать избавиться от repartition streams, соединив при помощи apply таблицу с таблицей в которой будут дистинктные значения campaign_id, card_id, - но не знаю, насколько это у вас применимо, нужно экспериментировать. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 12:33 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
Индексированное представление сделать не получится -- наличествует функция max. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 12:55 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
invmИндексированное представление сделать не получится -- наличествует функция max. тогда придется считать отдельно это поле, будет ли так быстрее - сложно сказать, но попробовать проверить можно. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 13:26 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
Мистер Хенки, т.е. Вы предлагаете сделать индексированное представление, в котором будет вызываться мой запрос? Я боюсь, что это плохой вариант, т.к. во-1 эта таблица самая большая в БД, а во-вторых есть функции max. SomewhereSomehow , план во вложении . А что за значок там такой на хэш-джойне, не предупреждение о спилл, случайно? Это предупреждение о использовании tempbd, что не удивительно при таких объемах данных. SomewhereSomehow, после того, как создал предложенную статистику время выполнения не сильно уменьшилось. В любом случае, спасибо Вам за ответы, буду эксперементировать. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 13:59 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
_ч_Это предупреждение о использовании tempbd, что не удивительно при таких объемах данных. Это и есть spill. Т.е. слив в темпдб. Посмотрите, какая огромная разница в оценках. Сервер ошибается более чем в 10 раз. Соответственно и памяти выделает в 10 раз меньше чем нужно. Так что, я бы не спешил грешить на объемы. Если мультиколоночную статистику сервер при оценке не использовал, то посмотрите, какая статистика у вас по колонкам [Loyalty_DS].[dbo].[cur].campaign_id и [Loyalty_DS].[dbo].[cur].card_id. Есть ли она, актуальная ли она? Подробная ли? Может попробовать обновить эти две статистики с опцией with fullscan. Если все в порядке и это не помогает, попробуйте включить флаг 2301 2301 Флаг трассировки: включить дополнительные решения для оптимизации поддержки MSФлаг трассировки 2301 позволяет дополнительно оптимизации, которые зависят от запросов поддержки принятия решений. Этот параметр применяется для поддержки принятия решений обработки больших наборов данных. Можно включить флаг трассировки 2301 при запуске или во время сеанса пользователя. При включении флага трассировки 2301 при запуске, флаг трассировки имеет глобальную область действия. При включении флага трассировки 2301 в сеансе пользователя, флаг трассировки имеет областью действия сеанса. Он включает расширенное моделирование в оптимизаторе и изменяет оценку во многих случаях. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 14:28 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
SomewhereSomehow, Спасибо Вам большое за ответы. Я создал отдельно статистику по card_id, по campaign_id и по card_id,campaign_id. Обновил её. Не помогло. Запустил запрос с опцией option (querytraceon 2301) План в xml прикреплен. К сожалению, время выполнения сильно не поменялось. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 16:05 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
_ч_, Это интересно. План не прикрепился, кстати. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 16:09 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
Sorry, вот план ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 16:37 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
_ч_, Да, интересно, оценка улучшилась, но не на порядок. Можете выполнить скрипт и приложить получившийся xml-ник? Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 16:49 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
SomewhereSomehow, Во вложении ... |
|||
:
Нравится:
Не нравится:
|
|||
20.06.2013, 17:13 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
_ч_, Спасибо. Теперь есть репро, попробую посмотреть в чем там дело. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 10:25 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
Дык тры минуты - вполне ничего :) Сократить тоже можно... хранить агрегаты в отдельной таблице и пересчитывать значения по мере поступления... (это как альтернатива индексированного представления ) Забавный эффект option (maxdop 1) ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 11:39 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
buserДык тры минуты - вполне ничего :) Сократить тоже можно... хранить агрегаты в отдельной таблице и пересчитывать значения по мере поступления... (это как альтернатива индексированного представления ) Забавный эффект option (maxdop 1) Мы как раз от хранения и ушли в пользу вьюхи и перерасчета агрегатов. На небольшом количестве данных (около миллиона) всё работает за доли секунд, а когда всего лишь 46 млн записей работает аж 3 минуты. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 12:02 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
_ч_buserДык тры минуты - вполне ничего :) Сократить тоже можно... хранить агрегаты в отдельной таблице и пересчитывать значения по мере поступления... (это как альтернатива индексированного представления ) Забавный эффект option (maxdop 1) Мы как раз от хранения и ушли в пользу вьюхи и перерасчета агрегатов. На небольшом количестве данных (около миллиона) всё работает за доли секунд, а когда всего лишь 46 млн записей работает аж 3 минуты. При большом объёме данных хранить агрегаты выгодней с точки зрения времени отработки запроса, но невыгодно с точки зрения места ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 12:03 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
Сергей Викт._ч_Мы как раз от хранения и ушли в пользу вьюхи и перерасчета агрегатов. На небольшом количестве данных (около миллиона) всё работает за доли секунд, а когда всего лишь 46 млн записей работает аж 3 минуты.При большом объёме данных хранить агрегаты выгодней с точки зрения времени отработки запроса, но невыгодно с точки зрения местаможно выбирать количество хранимых агрегатов. то есть хранить не для каждой записи, а для некоторых контрольных точек (день/неделя/месяц) и в расчётах опираться на них ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 12:16 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
ShakillСергей Викт.пропущено... При большом объёме данных хранить агрегаты выгодней с точки зрения времени отработки запроса, но невыгодно с точки зрения местаможно выбирать количество хранимых агрегатов. то есть хранить не для каждой записи, а для некоторых контрольных точек (день/неделя/месяц) и в расчётах опираться на них Безусловно, всё зависит от конкретных задач и потребностей. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 12:25 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
Еще забыл добавить одну вещь. Если в таблице 2 млн записей, то запрос вернет ~ 700 тыс. строк, т.е. на каждый card_id, campaign_id по 2-3 записи. Не знаю, важно ли это. Код: sql 1. 2.
в среднем будет так: 00000000-0000-0000-0000-00000006CBAA 93D5874A-9435-E211-A324-00155DFA260E 2 00000000-0000-0000-0000-0000000A0FEA 93D5874A-9435-E211-A324-00155DFA260E 1 00000000-0000-0000-0000-00000003976A 93D5874A-9435-E211-A324-00155DFA260E 2 00000000-0000-0000-0000-0000000A0BAA 93D5874A-9435-E211-A324-00155DFA260E 3 00000000-0000-0000-0000-00000006C98A 93D5874A-9435-E211-A324-00155DFA260E 1 00000000-0000-0000-0000-00000005F54A 93D5874A-9435-E211-A324-00155DFA260E 3 00000000-0000-0000-0000-000000082DCA 93D5874A-9435-E211-A324-00155DFA260E 9 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 12:26 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
_ч_Еще забыл добавить одну вещь. Если в таблице 2 млн записей, то запрос вернет ~ 700 тыс. строк, т.е. на каждый card_id, campaign_id по 2-3 записи. Не знаю, важно ли это. Код: sql 1. 2.
в среднем будет так: 00000000-0000-0000-0000-00000006CBAA 93D5874A-9435-E211-A324-00155DFA260E 2 00000000-0000-0000-0000-0000000A0FEA 93D5874A-9435-E211-A324-00155DFA260E 1 00000000-0000-0000-0000-00000003976A 93D5874A-9435-E211-A324-00155DFA260E 2 00000000-0000-0000-0000-0000000A0BAA 93D5874A-9435-E211-A324-00155DFA260E 3 00000000-0000-0000-0000-00000006C98A 93D5874A-9435-E211-A324-00155DFA260E 1 00000000-0000-0000-0000-00000005F54A 93D5874A-9435-E211-A324-00155DFA260E 3 00000000-0000-0000-0000-000000082DCA 93D5874A-9435-E211-A324-00155DFA260E 9 Ну если рассматривать вариант хранения агрегированных значений, то важно, т.к. чем меньше результатов агрегации. тем меньше размер таблицы. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 12:29 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
Посмотрел планы и статистику. Что увидел хорошего: 1. Оценки улучшились, для второго хэша 187К на вход и 593К на выход против 2000К на вход 1015К на выход. Соответственно - пропал спилл. 2. Оценки, на выходе, совпадают с реальностью 1015К vs 1015K - это радует. Что плохого: 3. Оценки на этапе локальной агрегации сильно плохи. Реально 13149К против 2030К. Тут к сожалению, мы упираемся в ограничение модели. На этапе оптимизации, оптимизатор оценивает кардинальность самой первой глобальной агрегации как 1 015 180. Когда он разбивает агрегацию на две, локальную и глобальную, локальную (так что будет выполняться каждым потоком) моделирует как число доступных потоков * глобальная кардинальность, предполагая однородность данных. Число доступных потоков - половина он DOP. получается 1 015 180* (4/2) = 2 030 360. В реальности получается данные, внутри каждого локального куска, группируются вовсе не с такой плотностью, на которую рассчитывал оптимизатор и имеем сильное превышение. 1. Можно попробовать, сделать рерайт запроса, сджойнив его с временной таблицей, в которую предварительно записать card_id, campaign_id или их сочетания - нужно экспериментировать. Что-то похожее описано тут . 2. Можно попробовать, заменить hash group на stream group указав в конце запроса option(order group). Возможно, при таком типе группировки, искажения будут минимальны, в отличие от хэш группы. Только если использовать option(order group), нужно чтобы был индекс: [opt].[dbo].[cur].card_id Ascending; [opt].[dbo].[cur].campaign_id Ascending Который включает поля: [opt].[dbo].[cur].value; [opt].[dbo].[cur].discount; [opt].[dbo].[cur].remainder; [opt].[dbo].[cur].campaign_id; [opt].[dbo].[cur].card_id; [opt].[dbo].[cur].operation_type_id Т.е. по сути , добавить в ваш индекс idx_cur_campaign_id_inc, первым полем card_id. прим. Ради любопытства, кстати, можно попробовать отключить локальную/глобальную агрегацию, чтобы был один агрегат. Выполнить запрос с флагом option(querytraceon 8665). Только в продакшне этого не оставляйте, это ради спортивного интереса, как изменится время выполнения запроса, если сервер будет агрегировать в одном месте. Если способ 1 и 2 никак не помогут, а то что в примечании сделает только хуже, то скорее всего, больше ничего посоветовать не смогу, во всяком случае пока. Нужно будет еще подумать. В принципе план норм., за исключением плохих оценок в промежуточной агрегации. Можно начать смотреть на другие параметры сервера, например, ждет ли запрос долго пока ему выделится память. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 15:23 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
SomewhereSomehow, Огромное Вам спасибо за внимание и интерес к теме. Я переделал индекс idx_cur_campaign_id_inc и включил в него поле card_id. Без option(order group) уже вполне терпимые 1мин и 27 сек на 43 млн записей. Ради интереса включил опцию querytraceon 8665, время выполнения увеличилось до почти 2 минут. С order group примерно тоже самое, что и без, но с новым индексом. Спасибо ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 16:33 |
|
Повышение быстродействия выполнения запроса
|
|||
---|---|---|---|
#18+
_ч_, Не за что, мне и самому интересны такие вопросы. Вот, теперь мне нравится соотношение оценок и реального числа строк. Оценки от индекса не поменялись, т.к. статистика была, и по-прежнему моделируются как 2 030 360. Но, после построения подходящего индекса, оптимизатор сам (даже без подсказки order group) отказался от hash agg и использует stream agg (теперь в плане Stream Aggregate), что и было целью. На мой взгляд, план получился вполне нормальный, больше тут, имхо, вряд ли что вытянешь. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.06.2013, 16:59 |
|
|
start [/forum/topic.php?fid=46&tid=1706484]: |
0ms |
get settings: |
12ms |
get forum list: |
15ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
183ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
2ms |
others: | 19ms |
total: | 314ms |
0 / 0 |