Я понимаю, что этот вопрос немного расплывчатый, но я надеюсь, что кто-то может указать мне направление, на которое нужно смотреть.
Моя проблема в том, что у меня есть запрос в программе, которая управляетЦП на моем 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, что неверно.Истинный размер строки больше.
Однако даже при плохом плане выполнения я не понимаю, как этот запрос может выполняться для 24+часов без окончания.
Глядя на sys.sysprocesses
, я вижу, что последний тип ожидания равен SOS_SCHEDULER_YIELD
.
Вот ссылка на план выполнения запроса для товараquery.
Мой сервер имеет 8 процессоров и 24 ГБ памяти.Сам запрос возвращает около 27 000 строк, поэтому сервер должен быстро выполнить это.Эта программа работает годами без проблем, поэтому, я думаю, что-то изменилось в плане выполнения.DOP моего сервера 64.
Прав ли я, полагая, что проблема, скорее всего, связана с параллелизмом?Если да, то как это может быть причиной того, что запрос, который должен выполняться за одну или две секунды, будет использовать 100% ЦП более 20 минут и все еще не завершиться?
РЕДАКТИРОВАТЬ: в плане выполнения для неверного запросаЯ обнаружил, что одним из шагов является поиск индекса в области, где он в идеале должен выполнять поиск кластеризованного индекса.Поиск по индексу выполняется в таблице, содержащей около 20 000 000 строк, но индексированное поле обладает высокой избирательностью.Этот поиск по индексу подается во вложенный цикл (с параллелизмом) в плане запроса.Я все еще думаю, что проблема каким-то образом связана с параллелизмом.
Для справки, я могу запустить SELECT
для этой таблицы, используя некластеризованный индекс, и запрос занимает несколько секунд.