Yawn And Yawn
I’ve written a bunch about Eager Index Spools, and how to fix them, but I’ve always sort of left the “finding” part up to you, or pointed curious tuners to tools like sp_BlitzCache.
Recently though, I worked with a client who had Eager Index Spools so frequently that we needed to track them down specifically.
This is the plan cache query that I used to do it — they didn’t have Query Store enabled — and I wanted to share it.
WITH
XMLNAMESPACES
('http://schemas.microsoft.com/sqlserver/2004/07/showplan' AS x),
plans AS
(
SELECT TOP (10)
deqs.query_plan_hash,
sort =
SUM(deqs.total_worker_time / deqs.execution_count)
FROM sys.dm_exec_cached_plans AS decp
JOIN sys.dm_exec_query_stats AS deqs
ON decp.plan_handle = deqs.plan_handle
CROSS APPLY sys.dm_exec_query_plan(decp.plan_handle) AS deqp
CROSS APPLY deqp.query_plan.nodes('//x:RelOp') AS r (c)
WHERE r.c.exist('//x:RelOp[@PhysicalOp="Index Spool" and @LogicalOp="Eager Spool"]') = 1
AND EXISTS
(
SELECT
1/0
FROM sys.dm_exec_plan_attributes(decp.plan_handle) AS pa
WHERE pa.attribute = 'dbid'
AND pa.value > 4
)
GROUP BY deqs.query_plan_hash
ORDER BY sort DESC
)
SELECT
deqp.query_plan,
dest.text,
avg_worker_time =
(deqs.total_worker_time / deqs.execution_count),
deqs.total_worker_time,
deqs.execution_count
FROM sys.dm_exec_cached_plans AS decp
JOIN sys.dm_exec_query_stats AS deqs
ON decp.plan_handle = deqs.plan_handle
CROSS APPLY sys.dm_exec_query_plan(decp.plan_handle) AS deqp
CROSS APPLY sys.dm_exec_sql_text(deqs.sql_handle) AS dest
WHERE EXISTS
(
SELECT
1/0
FROM plans AS p
WHERE p.query_plan_hash = deqs.query_plan_hash
)
ORDER BY avg_worker_time DESC
OPTION(RECOMPILE, MAXDOP 1);
It’s maybe not the prettiest thing in the world, but it got the job done.
Thanks for reading!
Going Further
If this is the kind of SQL Server stuff you love learning about, you’ll love my training. I’m offering a 75% discount to my blog readers if you click from here. I’m also available for consulting if you just don’t have time for that and need to solve performance problems quickly.
Every time you drive me crazy with 1/0 literal… If I were showing it to my jobmates… funny crazy!