Предлагаю запрос, который отображает запросы с MS SQL-сервера, которые потребляют память в текущий момент (при выводе информации применяется фильтр, отсекающий запросы, потребляющие менее 500 МБ). Иногда с его помощью удаётся найти неэффективные запросы, которые следует рассмотреть повнимательнее и, возможно, оптимизировать или переписать.
Кратко приведу информацию о колонках:
- Данные о пользователе (имя и хост)
- Время запроса (request_time) и выделения (grant_time) памяти
- Объем запрошенной (requested_memory_kb) и выделенной (granted_memory_kb) памяти в килобайтах
- Информация по использованию памяти: сколько потребовалось (required_memory_kb), было использовано (used_memory_kb) и максимальное значение (max_used_memory_kb)
- Коэффициент "стоимости" запроса (query_cost)
- Время ожидания (wait_time_ms)
- Сам выполняющийся запрос (query_text)
- Информация о выполняемом запросе (event_info)
- Ссылка на план выполнения запроса (query_plan)
-- запросы в текущее время потребляющие память
SELECT mg.session_id,
CAST(es.nt_user_name as varchar) as nt_user_name,
CAST(es.host_name as varchar) as host_name,
mg.request_time,
mg.grant_time,
mg.requested_memory_kb,
mg.granted_memory_kb,
mg.required_memory_kb,
mg.used_memory_kb,
mg.max_used_memory_kb,
mg.query_cost,
mg.resource_semaphore_id,
mg.wait_time_ms,
st.[text] as query_text,
ib.event_info,
qp.query_plan
FROM sys.dm_exec_query_memory_grants AS mg
INNER JOIN sys.dm_exec_sessions AS es
ON es.session_id = mg.session_id
CROSS APPLY sys.dm_exec_input_buffer(mg.session_id, NULL) AS ib
CROSS APPLY sys.dm_exec_sql_text(mg.sql_handle) AS st
CROSS APPLY sys.dm_exec_query_plan(mg.plan_handle) AS qp
WHERE mg.requested_memory_kb > 500000
ORDER BY mg.requested_memory_kb DESC
С помощью этого запроса обнаружили у себя запросы с аномальным потреблением памяти (10Гб, 20Гб и даже 40Гб).