Цель: изучить
влияние параллелизма 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) нашел поиском, однако там же
(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…. )))
Я думаю станет понятно, что ускорять надо больше саму 1с + ускорять канал связи 1С с SQL.
(46) а замедляльщикам SQL, я бы рекомендовал этого не делать
MDOP = 37
Кто мне скажет что надо ставить 0 или 1 заплюю пока не захлебнётесь!!!
(48) это у вас такая манера задавать вопросы?
(49) Ну нет :). Просто при отключенном параллелизме книга продаж за месяц крутится более 6 часов при включенном около 30 — 35 минут.
(50) Логично