Предлагаю запрос, который отображает запросы с 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Гб).