何时创建了多个执行计划?

时间:2014-04-23 18:30:47

标签: sql-server

想象一个名为dbo.TheBestCodedProcedure的过程,如果它以下列方式执行:

EXEC dbo.TheBestCodedProcedure

并且

EXEC TheBestCodedProcedure

两者都会成功执行,但会创建多少执行计划?我的理解是,执行计划基于被调用对象的名称和提供的参数。我已经看到了多个执行计划的例子,即使提供了相同的参数,唯一的区别是dbo.前缀,这是真的还是不正确? WHEN 创建额外执行计划的规则是什么?

2 个答案:

答案 0 :(得分:3)

要回答原始问题,请尝试以下操作:

create procedure dbo.proc_test
@i int
as
select @i
go

exec proc_test 1
exec dbo.proc_test 2
go

select usecounts, text
from sys.dm_exec_cached_plans
cross apply sys.dm_exec_sql_text(plan_handle)
where text like '%proc_test%'
and text not like '%dm_exec_cached_plans%'

正如您所见,缓存中只有一个计划。

有关计划可用性和可重用性的完整讨论,请参见此处:

http://technet.microsoft.com/en-us/library/ee343986%28v=sql.100%29.aspx

IMO这个题目太宽泛,不能在这里详细讨论。

答案 1 :(得分:2)

您在问题中显示的两个语句的唯一区别是,在一个语句中,您使用了TWO PART NAME,即[Schema].[Object],而在其他语句中,您只使用了对象名称来调用该过程。

这对存储过程的执行计划没有影响,但它确实对sql server如何找到这个存储过程产生了影响。

最好使用两个部分名称,因为它不需要解析模式,并且sql server执行此过程的工作量较少。

架构名称

另一方面,如果在调用存储过程时不使用两部分名称,则sql server必须经过几个步骤才能找到存储过程,如下所示。

  1. 它在当前数据库的sys架构中查找该过程。
  2. 如果它在sys模式中找不到它在Caller's Default Schema中查找的内容。
  3. 如果不在那里,那么如果从另一个过程内部调用此过程,则查看外部调用过程的模式。
  4. 如果它找不到它,那么它最终会在dbo模式中查找该过程。
  5. 正如您在调用过程时添加模式名称所看到的那样可以为sql server节省一些工作,因此在sql server中调用过程时最好使用模式名称。

    执行计划

    当我们在Sql server中执行Sql Query时,Sql Server会经过4个步骤才能成功执行查询。

    1. 解析语法。
    2. 转换为查询树。
    3. 创建执行计划。
    4. 执行。
    5. 在存储过程的情况下,只有在创建存储过程时才会执行前两个步骤。
      第一步是在第一次执行存储过程时发生。
      最后,每个后续执行都会进行第4步。

      现在可以出于多种原因制定执行计划。其中一些是

      • 存储过程暂时没有执行并且已缓存 计划已从缓存中刷新。
      • 索引已被删除或添加到基础表中。
      • 统计数据已更新。
      • 使用重新编译选项执行存储过程。