Sql-server – Plan changes to include Eager Spool causes the query to run slower

execution-planindex-spooloptimizationsql serversql-server-2016

We have a reporting query which is erratic in terms of execution plan and run duration.
It is either 5 seconds or as slow as 5 minutes.
The query is a Select statement with no DML involved.
One thing I noticed is the costly Eager Spool operator after an index scan in slow executions.
However, index seek is used when executing fast.
I updated the stats but it didn't help to speed up.
I was just wondering why sometimes optimiser chooses to use Index Scan (and Eager Spool) rather than Index Seek and what causes it to do so?
Attaching SS of both slow and fast execution plans. SS is saved as a file from Plan Explorer so may upload some other tabs if need be.
Thank you
Edit: The query runs fast in the mornings, slow in the afternoons, always.

Fast execution
Slow execution

Best Answer

Your queries are using totally different indexes, which means the optimizer is choosing different plans based on different parameters.

You're able to see the difference with the recompile hint (which means parameter sniffing is involved), which is good. How you fix it is up to you.

In the fast plan, these indexes get used:

NUTS

Object 13: Index 2, Object 12: Index 3, Object 7: Index 4.

In the slow plan, these get used.

NUTS

Object 13: Index 3, Object 12: Index 4, Object 7: Index 5.

Since the plan is anonymized, and you've only posted pictures of it, what you need to do is look at which parameters were used in each execution, and try out using the OPTIMIZE FOR (please for the love of Joe Sack don't use UNKNOWN) hint to see if the 'fast' plan is still fast for the set of parameters used to get the slow plan.

It may not be, which is totally possible. From there, you'd need to look at the query and indexes to tune things so you have a better general plan. It'll be really hard to help if you keep posting anonymized stuff, though.