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: these days I have AI do the annoying stuff for me. My new video course teaches you to work the same way, and I teach whole teams in a one-day workshop. Someone still has to know enough SQL Server to keep the robots in check, and that’s what my training is for.
Every time you drive me crazy with 1/0 literal… If I were showing it to my jobmates… funny crazy!