Может ли параллелизм вызвать 100% загрузку процессора? - PullRequest
0 голосов
/ 11 октября 2018

Я понимаю, что этот вопрос немного расплывчатый, но я надеюсь, что кто-то может указать мне направление, на которое нужно смотреть.

Моя проблема в том, что у меня есть запрос в программе, которая управляетЦП на моем SQL Server до 100%.Я думаю, что проблема связана с параллелизмом, но я не знаю, как подтвердить свое подозрение или лучший способ решить эту проблему.

В рассматриваемом запросе около 20 минут работало сервер при 100% CPU, в этот момент я убил запрос.Я использовал sys.dm_exec_query_stats, чтобы посмотреть план выполнения запроса.Там нет индекса сканирования.Индексные операции все ищут.Я уверен, что мои индексы хорошо подобраны для этого запроса.Я вижу много параллелизма в запросе.

Для сравнения, я попытался выполнить тот же запрос в окне запроса в Management Studio.Запрос выполняется не более, чем за несколько секунд, а кнопка «Показать примерный план выполнения» дает мне другой план выполнения.Одно из отличий в этом плане выполнения заключается в том, что здесь нет параллелизма.

Вот ссылка на план выполнения запроса для неверного запроса. Одна вещь, которая выглядит как проблема, этопри поиске кластеризованного индекса на PS_TRANSACTION_INV с предикатом на PS_TRANSACTION_INV.BUSINESS_UNIT (полностью справа в плане выполнения) отображается 1 предполагаемая строка.Все, кроме нескольких сотен строк, имеют значение TRUS1, а остальные строки имеют значение TRCN1.Таблица имеет около 15 миллионов строк и использует около 22 ГБ (поэтому строки довольно большие).Я сделал DBCC SHOW_STATISTICS для кластеризованного индекса таблицы, и статистика выглядит корректно (как показано ниже).План выполнения также имеет приблизительный размер строки 54 B, что неверно.Истинный размер строки больше.

enter image description here

Однако даже при плохом плане выполнения я не понимаю, как этот запрос может выполняться для 24+часов без окончания.

Глядя на sys.sysprocesses, я вижу, что последний тип ожидания равен SOS_SCHEDULER_YIELD.

Вот ссылка на план выполнения запроса для товараquery.

Мой сервер имеет 8 процессоров и 24 ГБ памяти.Сам запрос возвращает около 27 000 строк, поэтому сервер должен быстро выполнить это.Эта программа работает годами без проблем, поэтому, я думаю, что-то изменилось в плане выполнения.DOP моего сервера 64.

Прав ли я, полагая, что проблема, скорее всего, связана с параллелизмом?Если да, то как это может быть причиной того, что запрос, который должен выполняться за одну или две секунды, будет использовать 100% ЦП более 20 минут и все еще не завершиться?

РЕДАКТИРОВАТЬ: в плане выполнения для неверного запросаЯ обнаружил, что одним из шагов является поиск индекса в области, где он в идеале должен выполнять поиск кластеризованного индекса.Поиск по индексу выполняется в таблице, содержащей около 20 000 000 строк, но индексированное поле обладает высокой избирательностью.Этот поиск по индексу подается во вложенный цикл (с параллелизмом) в плане запроса.Я все еще думаю, что проблема каким-то образом связана с параллелизмом.

Для справки, я могу запустить SELECT для этой таблицы, используя некластеризованный индекс, и запрос занимает несколько секунд.

1 Ответ

0 голосов
/ 16 октября 2018

Мой первый вопрос: какие типы ожидания вы видели?

Во-вторых, как настроен ваш сервер (возможно, запустите sp_Blitz и дайте нам вывод sp_Blitz @OutputType = ‘markdown’, @CheckServerInfo = 1)?

В-третьих, что-нибудь еще работает, вызываягорлышко бутылки?Возможно, начните с sp_BlitzFirst или sp_whoisactive , чтобы увидеть, что происходит.

Может ли параллелизм вызвать 100% загрузку ЦП?

Конечно можно. Брент написал запрос, чтобы сделать именно это .Или, по крайней мере, он использует MAXDOP 0, чтобы убедиться, что это происходит быстрее?

Для сравнения я попытался выполнить тот же запрос в окне запросов в Management Studio.Запрос выполняется не более, чем за несколько секунд, и кнопка «Показать примерный план выполнения» дает мне другой план выполнения

Я не работаю с Брентом, , но он тоже об этом говорит. .Вам необходимо использовать фактический план выполнения, а не предполагаемый. Добавление его сюда и включение ссылки в ваш пост полезно.Кроме того, вам необходимо определить, использует ли приложение кэшированный план процедур, или они оба используют новые планы.Вы можете использовать option(recompile), чтобы создать новый план и сравнить яблоки с яблоками (но, как красный, вкусный с бабушкой Смит, которая лучше, чем яблоки с апельсинами)

Сам запрос возвращает около 27 000 строк, поэтомуэто должно быть в пределах возможностей сервера, чтобы выполнить это быстро.

Число final , столь малое, не должно быть показателем того, почему он работает плохо.Где-то в N числах соединений могут быть миллионы строк, отведенных назад до того, как будет оценен последний предикат.Вот где фактический план выполнения покажет вам узкие места.

DOP моего сервера составляет 64

Кажется высоким, но вы не сказали нам все о количестве ядерты бегаешь.К счастью, У Microsoft есть хорошее руководство по этому вопросу. .Прежде чем перейти к изменению его на уровне сервера, добавьте подсказку в конец запроса ... option(maxdop 8).Кроме того, я ожидал бы увидеть CXPACKET ожидания, если бы это был параллелизм. Вот видео об этом. .

Наконец, помните, что оптимизация запросов трудна , даже для сервера.Конечно, это не так, поскольку ваше приложение работает вечно, а SSMS быстро возвращает данные, и именно здесь я ожидаю увидеть ASYNC_NETWORK_IO ожиданий или что-то в этом роде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...