I built a stored procedure which finds the shortest route in a company with many warehouses. The procedure is heavily used by the system. After many optimizations, including memory optimized tables, if I run sp_BlitzCache, I have 2 warnings:
- Parameter Sniffing;
- You have 83866 total plans in your cache, with 100.00% plans created in the past 24 hours, 100.00% created in the past 4 hours, and 100.00% created in the past 1 hour.
The procedure is called only with parameters (no hardcoded values). You can find here a query plan: https://www.brentozar.com/pastetheplan/?id=r1rW59QvN.
I really don't understand why the engine generates for each execution a plan and what I should check. Also, sp_BlitzCache says We couldn't find a plan for this query. Possible reasons for this include dynamic SQL, RECOMPILE hints, and encrypted code. I don't have either dynamic SQL, recompile hints nor encrypted code.
What should I check?
UPDATE
I checked the impact of this procedure on the server as Jeroen Mostert suggested in the comments (thank you for your response!) and this procedure uses 0.66% of top 10 procedures on the server regarding average IO, but is the only procedure without a plan, so the question still remains: why so many plans?
I haven't tried to run the stored procedure without the memory optimized tables. I had to use them because the proc needs to run as fast as lightning (and runs in less then 30 milliseconds in some cases). Also, I don't have the guts the procedure without the tables memory optimized, because I cannot reproduce the workload on test servers.
Thank you!
OPTION (KEEP[FIXED] PLAN)
for the parts of the procedure that are suspected sources of recompilation (again, the memory-optimized tables spring to mind). Obviously, some care needs to be taken to ensure this does not cache an inappropriate plan, but it can cut down considerably on unnecessary compilations. (I don't know if it has any effect with memory-optimized tables, I've only ever used it for disk-based tables.)