我正在研究SQL Server 2008 R2。
我有一个存储过程Rpt_RegionReport
。它至少运行过一次,所以我可以说它是编译。它在缓存中有一个条目,我可以在sys.dm_exec_cached_plans
中看到。
现在,我使用plan_handle
并通过调用DBCC FREEPROCCACHE
并将plan_handle
传递给缓存,将其从缓存中删除。我确认它已不再存在缓存中的条目。
现在,你认为这个存储过程仍然被认为已编译,尽管它在缓存中没有条目吗?
或
你认为这个存储过程现在被认为是未编译,因为它在缓存中没有条目吗?
我想知道SQL Server何时将存储过程视为未编译和已编译。
由于
答案 0 :(得分:1)
如果计划缓存中没有条目,我会说“未编译”。下次调用时,需要对其进行解析和编译。
为了清楚起见,计划不会永远缓存。重新启动SQL Server服务,调用DBCC FREEPROCCACHE时清除缓存,如果系统需要添加更多计划并且计划缓存中的空间不足,它将开始删除尚未使用的旧计划而
修改强>
此外,它有助于澄清术语“已编译”,因为它与编译为EXE或DLL的C#/ C ++ / VB.NET / F#不同。查看sys.dm_exec_cached_plans的MSDN页面。我们在这里讨论“查询计划”,这些计划可以用于各种不同的对象类型,包括Ad Hoc查询。不要忘记FREEPROCCACHE
的名字,认为你真的在处理程序本身。 “FREE PROC CACHE”中的术语“PROC”可能来自旧版本的SQL Server(2000或更早版本),当缓存可能只包含存储过程的计划时。
并且,由于您需要向您的经理解释这一点,因此应该指出“已编译”的“查询计划”是SQL Server将执行查询的“方式”。它是JOIN的类型,当某些事情完成时,例如执行函数和排序等。有许多方法可以执行每个查询,而计划缓存允许SQL Server可能跳过它花费的时间通过重复使用上次提出的答案(无论是一个好的答案还是一个错误的答案)来计算(即“编译”)试图寻找最佳方法时的变化。
答案 1 :(得分:1)
你认为这个存储过程仍然被考虑编译虽然它 缓存中没有条目?
AFAIK,只有当存储过程第一次运行而不是在编译之后,才会在sys.dm_exec_cached_plans
中获得一个条目。此外,程序的编译按需进行。例如,如果您刚刚创建了该过程,那么它可能尚未编译,但是当您第一次运行它时,它会被编译并且已编译的计划被缓存以供重用。
所以,否它不再编译了。运行DBCC FREEPROCCACHE
将使优化程序在内存中缓存的所有存储过程计划无效,并强制SQL Server
在下次运行这些过程时编译并生成新计划。再次运行它将重新生成并缓存计划。
如果要生成新计划但又不想重新使用缓存计划,则可以在过程正文中使用WITH RECOMPILE
选项。