Quick tip from me today: I recently had to check on which T-SQL query / queries in the system were using up some monster 30GB+ query grants. Luckily the sys.dm_exec_query_memory_grants DMV facilitates this. Here is the query I finally used to figure out what was happening:
SELECT r.session_id
,mg.granted_memory_kb
,mg.requested_memory_kb
,mg.ideal_memory_kb
,mg.request_time
,mg.grant_time
,mg.query_cost
,mg.dop
,(
SELECT SUBSTRING(TEXT, statement_start_offset / 2 + 1, (
CASE
WHEN statement_end_offset = – 1
THEN LEN(CONVERT(NVARCHAR(MAX), TEXT)) * 2
ELSE statement_end_offset
END – statement_start_offset
) / 2)
FROM sys.dm_exec_sql_text(r.sql_handle)
) AS query_text
,qp.query_plan
FROM sys.dm_exec_query_memory_grants AS mg
INNER JOIN sys.dm_exec_requests r ON mg.session_id = r.session_id
CROSS APPLY sys.dm_exec_query_plan(r.plan_handle) AS qp
ORDER BY mg.required_memory_kb DESC;
In case you are wondering what memory grants are all about, you should start from this great blog post from Jay Choe, who is part of the SQL Server development team. Jay also posts some useful variants of queries to find out (for example) cached query plans with memory grants. It is a great read.
Happy query tuning!