Цель: изучить
влияние параллелизма SQL
на работу с запросами 1С
Литература:
Понимание и использование параллелизма в SQL Server
Тестовая среда:
·
Windows
server 2008 R2 Enterprise
·
MS
SQL server 2008 R2
·
1С Предприятие 8.2.19.90
SQL properties:
Рисунок 1. SQL
properties “General”
Рисунок 2.
SQL properties “Advansed”
Инструменты:
·
SQL
server profiler
·
SQL
Query
·
Консоль запросов 1С
Тестовый запрос:
ВЫБРАТЬ
АК.Наименование КАК Наименование
ИЗ
РегистрСведений.АдресныйКлассификатор
КАК АК
ВНУТРЕННЕЕ
СОЕДИНЕНИЕ РегистрСведений.АдресныйКлассификатор КАК АК1
ПО
АК.Код = АК1.Код
Подготовка:
Запускаем SQL server Profiler,
устанавливаем соединение, отмечаем события и колонки как показано на рисунке 3.
Рисунок 3. Trace properties
Устанавливаем отбор для нашей базы
Рисунок 4. Фильтр по базе
Сокращения:
·
Max
degree of parallelism – MDOP
·
Сost threshold for parallelism — cost
Тестирование последовательного плана запроса (MDOP = 1)
Далее, в среде 1С Предприятие в тестовой базе запускаем
консоль запросов и выполняем запрос (Рис.5)
Рисунок 5. Консоль запросов – время выполнения 20 сек.
Параметр SQL сервера “Max degree of parallelism”
установлен в 1 (без параллелизма).
Смотрим результат в профайлере (рис.6)
Рисунок 6. Последовательный план запроса
SQL
сервер сформировал последовательный план запроса, при этом: общая загрузка CPU = 6,750 (сек), а время на
выполнение запроса = 7,097(сек)
Тестирование параллельного плана запроса (MDOP = 0, cost =5)
Переводим SQL server в режим параллелизма (в SQL Query):
USE
master;
GO
EXEC
sp_configure ‘show advanced option’,
1;
GO
RECONFIGURE
WITH OVERRIDE
USE
master;
GO
exec
sp_configure‘max degree of parallelism’,
0;
GO
RECONFIGURE WITH
OVERRIDE
Выполняем тот же запрос (Рисунок 7)
Рисунок 7. Консоль запросов – время выполнения 16 сек.
Проверяем результат в профайлере (Рисунок 8)
Рисунок 8. Параллельный план запроса
Сервер SQL
в этот раз сформировал параллельный план запроса, при этом общая загрузка CPU = 7,905 сек, а
длительность выполнения запроса = 3,458 сек
Тестирование последовательного плана запроса (MDOP = 0, cost = 150)
Попытаемся избавиться от
параллельного плана, используя параметр «Сost threshold for parallelism». По умолчанию
параметр установлен в 5. В нашем случае от формирования параллельного плана
удалось избавиться при значении 150 (в SQL Query):
USE
master;
GO
exec
sp_configure ‘cost threshold for parallelism’, 150 ;
GO
Проверяем выполнение запроса в данных
условиях (рис. 9)
Рисунок 9. Консоль запросов – время выполнения
20 сек.
Проверяем результат в профайлере (рис.10)
Рисунок 10. Последовательный план
запроса.
Сервер SQL сформировал последовательный план запроса. Общая загрузка CPU = 7,171 сек, время выполнения запроса =7, 864 сек.
Выводы:
·
Выполнение тестового запроса в среде 1С
Предприятия с использованием SQL
сервером параллельного плана запроса дает значительный прирост
производительности по сравнению с последовательным планом (16 сек. против 20
сек. – выигрыш 4 сек.)
·
Выполнения тестового запроса самим сервером SQL при
использовании параллельного плана запроса происходит в два раза быстрее, чем при
использовании последовательного плана запроса (3,5 сек. против 7,1 сек.)
·
Параллелизм SQL сервера можно регулировать не только, используя параметр MDOP, но и параметр «Сost
threshold for parallelism»
Почему-то после прочтения возникает ощущение исследования сферического коня в вакууме. Хотя читалось не без интереса и за труды не могу не поставить плюса. Но…
Во-первых, удручает практичность выводов… Учитывая то, что самим техсапом MS не рекомендуется менять значение параметра ctfp, а также то, что понятие стоимости запроса неизвестно в каких попугаях меряется (об этом красноречиво говорит разница между значением ctfp и фактическим временем исполнения запроса) — напрашивается вывод о нецелесообразности оперирования данным инструментом. Кстати, вопрос: а UPDATE STATISTICS перед замерами делался? а то может 150 и получилось из-за неверной предварительной расценки стоимости запроса?
Во-вторых, hash match по декартову произведению одной из крупнейших таблиц (в среднестатической ИБ) самой на себя вряд ли можно назвать достаточно репрезентативной операцией для оценки такой глобальной настройки, как ctfp.
Ну и в-третьих, если уж идти в отрыв от реальности и оценивать синтетические результаты, то куда интереснее посмотреть выигрыш при параллельном выполнении TABLE SCAN, а не при переборе упорядоченного индекса. И вообще пойдёт ли оптимизатор на распараллеливание при TABLE SCAN?
(1) с обновлением и без обновления статистик результаты схожие. Относительно ctfp и техсапа, хотелось бы увидеть ссылочку. Все выводы сделаны по конкретному запросу в конкретной тестовой среде.Про Table Scan пока не могу сказать. Параллелизм накладывает ряд ограничений. В одной из статей мне попадалась эта тема.
(2)Степень параллелизма
(3) ссылка не открывается
(3) нашел поиском, однако там жеhttp://technet.microsoft.com/ru-ru/library/ms188603(v=sql.105).aspx
(1) Table Scan тоже параллелится, попробую потестировать
(5) да это именно та статья… почему-то то ссылка при вставке «побилась»…
(6) практически не сомневался в этом, потому как сегментировать перебор кучи вполне логично для оптимизатора при доступной возможности распараллеливания операций. Интересен размер эффекта… пусть даже на синтетическом примере…
(8) SELECT
Count(*)
FROM [ExchangeDB].[dbo].[_Employee_Changes] as Part1
LEFT JOIN [ExchangeDB].[dbo].[_Employee_Changes] as Part2 ON Part1._IDRRef = Part2._IDRRef
Описанный выше запрос на неиндексированной таблице при параллельном плане дает двойной прирост (0,250) против (0,573). Запрос возвращает 260603669
Алексей, жду исследования сферического коня в PostgreSQL. Мне MS SQL не дают =(
(10) мы пока на скуле сидим
Статья удивила… Вообще max degree of parallelism ставят в 1 изначально потому что MS SQL при параллельном исполнении накладывал «непонятные блоикровки»и доходило до DeadLock — ов. На текущей версии (2012) ничего не поменялось… если только в 2014 что-то «доделали». Во-вторых 1С это же СКД + Консоли запросов/отчетов всякие… если в базе 300+ пользователей и куча разных «фич» то установка данного свойства не в «1» приводит к «убиению» SQL сервера неправильным запросом… или правильным, но 1 пользователь мешает работе остальных 300…
А показать что использование нескольких ядер вместо одного даёт преимущества можно к примеру и на MS Excel если его запустить с нужным Affinity…
(12) у нас работает на 2008 R2 SQL server проблем не отмечается. Все-таки, хотелось уточнить на каких конфигурациях сервера вы рекомендуете ставить MDOP в 1
(12) к тому же не все запросы выполняются параллельно и параллелизм можно регулировать параметром «Сost threshold for parallelism»
Каким образом было снижено или исключено влияние процедурного и буферного кэшей на производительность выполняемых (в ходе тестов) запросов?
(12) comol, На 1С мне известен только один нормальный кейс когда возможно выставлять 0. Это обновление информационной базы с реструктуризацией. Лет 5 назад, еще до 8.3 и фонового обновления использовали такой вот хинт подсмотренный у DBA, которые так оптимизировали BULK INSERT операции.
код скрипта выглядел так на псевдо языке
В остальных случаях согласен — Maxdop = 1 на весь сервер. Чистые SQL специалисты играются с хинтами в запросах, у нас же такой возможности нет.
(16) lustin, соврал насчет нет возможности. Есть… Но очень дорого
(17) lustin, это параллелизм на уровне прикладного кода, а не запросов, и к обсуждаемой тематике отношения не имеет.
(15) использовался dbcc freeproccache, но заметного влияния замечено не было
(16) для параллелизма необязательно выставлять MDOP в 0, достаточно установить отличным от 1
(19) уже лучше, но почему в статье об этом ничего не написано? А что насчет буферного кэша? Или на ваш взгляд его состояние (как и состояние процедурного) незначительно влияет на скорость выполнения запросов?
(21) где можно посмотреть данные о влиянии буферного кэша на скорость выполнения запроса?
(21) уточнения по тому же запросу:
после
CHECKPOINT
DBCC FREEPROCCACHE
GO
dbcc dropcleanbuffers
GO
MDOP = 1 первый раз — 40,739 сек, второй раз — 7,116 сек
MDOP = 0 первый раз — 15,803 сек, второй раз — 3,498 сек
проверил, SQL 2008 — на четырех серверах MDOP = 0.
настройки на серверах «по умолчанию», поэтому что-то не совсем понял на счет споров об отмене «MDOP = 1» —
изначально и так «MDOP = 0», разве нет? 🙂
(24) некоторые настойчиво рекомендуют устанавливать MDOP = 1, без вариантов
(12) кстати, столкнулся с тем, что не для всех очевидно «что использование нескольких ядер вместо одного даёт преимущества», поэтому пришлось проделать данную работу
(23) ну вот уже лучше. Теперь понятно что этот конкретный select в лабораторных условиях при mop<>1 выполняется быстрее. А теперь откройте тайну, какую практическую ценность несет эта информация?
(27) лично для меня одно из направлений повышения производительности
(28) ну так возьмитестандартный нагрузочный тест и докажите, что применение параллелизма существенно повышает производительность при многопользовательской работе.
(24) zoytsa, MDOP=0 есть настройка, разрешающая параллелизм и не ограничивающая количество CPU, участвующих в запросе. MDOP=1 ограничивает количество CPU, участвующих в исполнении запроса, одним и таким образом запрещает параллелизм.
(29) у меня уже есть такие данные
(28) В таком случае я предлагаю перенести эти исследования в ваш личный блог. Потому как запуск одного запроса (отражающего специфику работы вашей системы) в лабораторных условиях, ничего не доказывает. Кроме того не раскрыты методы борьбы с ошибками СУБД:
— «Intra-query parallelism caused your server command (process ID #XX) to deadlock. Rerun the query without intra-query parallelism by using the query hint option (maxdop 1)»
— «Transaction (Process ID #XX) was deadlocked on thread communication buffer resources with another process and has been chosen as the deadlock victim»
(32) вы предлагаете в одной работе затронуть такие темы, каждой из которой посвящаются отдельные работы?
Intra-query parallelism caused your server command… зачастую не ошибки СУБД а кривой код.
Я бы с удовольствием, заблокировал эту статью, коль у Вас она вызывает такое раздражение, однако, я наблюдаю некоторый интерес со стороны других читателей и не хотелось бы их подводить
(33) не надо блокировать. Вы затронули достаточно больную и серьезную тему. В эту сторону так или иначе смотрели многие. Просто единого подхода так и не выработалось. Точнее скажу немного по другому «В Prodcution решениях на 1С многие отказались от исследования данной тематики»
Оказалось, что дешевле, по затратам времени и по затратам на поддержку, реалилизовывать парралельность на уровне кода ORM.
Предвосхищу, что настоящие DBA меня сейчас закидают «тряпками», но все же, я не зря дал выше пример кода от СофтПоинта на чистом 1С.
Обычно в 1С, да и не в 1С смотрят в сторону адаптации метаданных (таблиц СУБД) и кода контролера под многопоточность выборок. Здесь необходимо явно управлять блокировками по ключам, одновременно с этим обратить внимание на сортировку индексных выражений. Но зато слияние данных происходит на уровне сервера приложений — то есть там где также существует возможность организовать и кэш частично рассчитанных данных.
То есть фактически это такой MapReduce подход (с большой конечно натяжкой). И в этом случае задача сервера СУБД обеспечить многопоточное выполненение транзакций на чтение небольших наборов данных, а уже сервер приложений обеспечит агрегирование на уровне контролера или агрегатов таблиц: но в общем случае это более управляемый процесс, потому что код открыт для вас как разработчика.
Также при использовании кода фрэймворка для реализации парралельности выполнения операций с СУБД, оказалось проще «разруливать» те самые «дедлоки», так как явно понятно какой участок кода какой участок кода блокирует. А не разбираться между сессиями и кэшем SQL запросов, которые НЕ совсем прозрачны для этих целей.
Вместе с тем, я еще раз повторюсь — не обращайте внимание на наше ворчание в комментариях. Если вы решили исследовать этот вопрос — это уже круто, не каждый решится на такое. Да и мой комментарий не яляется истиной в последней инстанции.
(34) lustin,
целесообразно лишь при наличии уверенности в существенном положительном эффекте от использования параллелизма при многопользовательской работе. В чем лично я совсем не уверен.
Если речь о физических чтениях — мы по определению не можем их выполнять параллельно, шина-то одна. В целом параллелизм позволяет более эффективно использовать ресурсы нескольких CPU, но наращивая нагрузку, упираемся мы, как правило, совсем не в CPU и даже не на стороне SQL.
(36) asved.ru, полностью согласен. у меня сложилось такое же мнение, просто я его не так конкретно формулирую.
(34) lustin,
согласен с Вами,
чем ждать панацеи на уровне базы данных, лучше оптимизировать сами запросы;
особенно когда, как Вы заметили, источник блокировки ясен — зачем менять курс всего корабля 🙂
(36) asved.ru,
А вот тут можно детальнее? Во что? )
автор лучше бы восстановление последовательности потестил
(40) а причем тут восстановление последовательности?
(41) при том, что это намного более «жизненное» тестирование, чем один огромный джоин. Для случая из статьи понятно, что параллелизм даст выигрыш. А вот для кучи мелких запросов, которые составляют большую часть алгоритмов прикладных решений, ситуация может быть другой (вплоть до замедления ;)).
многопоточный тест (который, конечно, тоже жутко синтетический) с разными настройками параллелизма и посмотрите, как изменится масштабируемость от этих настроек.
Ну и до кучи — может быть вы попробуете
(42) мелкие запросы не параллелизируются, нужно очень сильно изгаляться, чтобы добиться этого — для этой задачи нужно пробовать другие механизмы, первое, что приходит на ум — ручной параллелизм или многопоточность
многопоточный попробую
Почему в качестве теста выбран джойн таблицы с самой собой? Есть что-нибудь более жизненное?
(44) запрос приведен в качестве примера, готовых рецептов нет, нужно смотреть, экспериментировать, подбирать оптимальный вариант. Посмотрите предыдущие и последующие публикации на эту тему, возможно, попадется что-то жизненное
а я бы рекомендовал лучше — всем ускоряльщикам SQL почитать про ORM…. )))
https://ru.wikipedia.org/wiki/ORM
Я думаю станет понятно, что ускорять надо больше саму 1с + ускорять канал связи 1С с SQL.
(46) а замедляльщикам SQL, я бы рекомендовал этого не делать
MDOP = 37
Кто мне скажет что надо ставить 0 или 1 заплюю пока не захлебнётесь!!!
(48) это у вас такая манера задавать вопросы?
(49) Ну нет :). Просто при отключенном параллелизме книга продаж за месяц крутится более 6 часов при включенном около 30 — 35 минут.
(50) Логично