Вы когда-нибудь задумывались о том, как SQL Server управляет выполнением пользовательских запросов и как он отображает их на разные ЦП? В этой статье блога мы рассмотрим концепцию конкуренции ЦП в SQL Server и способы определения, какие запросы выполняются на определенном ЦП.
SQL Server использует планировщики для управления выполнением пользовательских запросов. Каждый планировщик отображается на ЦП, что означает, что на каждый планировщик приходится один ЦП. Например, если ваша система имеет 8 ЦП, то будет 8 планировщиков ОС. Чтобы узнать количество существующих планировщиков ОС на вашем SQL Server, вы можете выполнить запрос к представлению sys.dm_os_schedulers:
SELECT COUNT(*) AS NO_OF_OS_SCHEDULERS
FROM sys.dm_os_schedulers
WHERE status='VISIBLE ONLINE'
Путем выполнения запроса к представлению sys.dm_os_schedulers вы можете точно определить, какие запросы выполняются на каком ЦП. Эта информация может быть чрезвычайно полезной, когда вы начинаете замечать признаки нагрузки на ЦП и хотите точно определить точку конкуренции – конкретный ЦП или планировщик и запрос, вызывающий привязку ЦП.
Чтобы получить более подробную информацию о текущих выполняющихся задачах, вы можете выполнить запрос к представлению sys.dm_os_tasks. Это представление возвращает одну строку для каждой активной задачи в экземпляре SQL Server. Столбец task_state показывает, является ли задача PENDING, RUNNABLE, RUNNING или SUSPENDED. Когда рабочий поток ожидает запуска на ЦП, он считается RUNNABLE и находится в очереди RUNNABLE. Чем дольше поток ожидает в очереди RUNNABLE, тем больше нагрузки на ЦП. Это время ожидания называется временем ожидания сигнала, и высокие времена ожидания сигнала указывают на узкое место ЦП.
Помимо task_state, представление sys.dm_os_tasks предоставляет другую полезную информацию, такую как scheduler_id, связанный с определенным session_id (или spid), pending_IO_Count, Context_Switches и task_address.
Чтобы получить фактический запрос, выполняющийся на ЦП, вам необходимо объединить представление sys.dm_os_tasks с представлением sys.dm_exec_requests. Представление sys.dm_exec_requests предоставляет информацию о каждом запросе, выполняющемся в SQL Server, включая wait_time, total_elapsed_time, cpu_time, wait_type, status и другие. Путем объединения этих двух представлений по столбцу task_address вы можете получить plan_handle, который необходим для получения текста SQL-пакета с помощью функции sys.dm_exec_sql_text.
Вот пример запроса, который объединяет все необходимые представления DMV и использует оператор APPLY:
SELECT *
FROM sys.dm_os_tasks AS t
INNER JOIN sys.dm_exec_requests AS r ON t.task_address = r.task_address
CROSS APPLY sys.dm_exec_sql_text(r.plan_handle) AS s
-- WHERE task_state='RUNNABLE' -- Чтобы отфильтровать сеансы, ожидающие ЦП
Этот запрос позволит определить точный запрос, выполняющийся на определенном ЦП и в какой базе данных. Вы можете увидеть task_state и статус команды, идентификатор объекта, статистику ожидания, cpu_time, количество физических и логических чтений и записей и многое другое! Если вы хотите увидеть только сеансы, ожидающие ЦП, вы можете отфильтровать запрос, используя “WHERE task_state=’RUNNABLE'”.
Понимание конкуренции ЦП в SQL Server и возможность определить, какие запросы вызывают ее, могут значительно помочь в настройке производительности. Используя оператор APPLY и запросы к соответствующим представлениям DMV, вы можете получить ценную информацию о использовании ЦП вашей системы и оптимизировать ее соответствующим образом.
Спасибо Мэтту Велику за организацию T-SQL Tuesday и предоставление возможности сообществу SQL поделиться своими знаниями и опытом!