添加SQL Server索引,但如何只重新编译受影响的存储过程?

时间:2009-05-08 16:36:39

标签: sql sql-server sql-server-2005 tsql indexing

我需要为表添加一个索引,我想只重新编译/所有引用该表的存储过程。有没有快捷简便的方法?

编辑:

来自SQL Server 2005联机丛书,重新编译存储过程:

由于通过添加索引或更改索引列中的数据等操作更改了数据库,因此应通过重新编译来再次优化用于访问其表的原始查询计划。重新启动Microsoft SQL Server 2005后,第一次运行存储过程时会自动执行此优化。如果存储过程使用的基础表发生更改,也会发生此问题。 但是,如果添加了一个新索引,存储过程可能从中受益,则优化不会发生,直到下次重新启动Microsoft SQL Server后运行存储过程。在这种情况下,它可能很有用强制存储过程在下次执行时重新编译

强制存储过程重新编译的另一个原因是在必要时抵消存储过程编译的“参数嗅探”行为。当SQL Server执行存储过程时,过程在编译时使用的任何参数值都包含在生成查询计划中。如果这些值表示随后调用过程的典型值,则存储过程每次编译和执行时都会从查询计划中受益。如果没有,性能可能会受到影响

3 个答案:

答案 0 :(得分:3)

它们通常会自动重新编译。我想我不知道这是否有保证,但它一直是我观察到的 - 如果你改变(例如添加一个索引)sproc引用的对象然后它重新编译。

create table mytable (i int identity)
insert mytable default values
go 100
create proc sp1 as select * from mytable where i = 17
go
exec sp1

如果您查看此执行的计划,它会按预期显示表扫描。

create index mytablei on mytable(i)
exec sp1

该计划已更改为索引搜索。

编辑:好吧我想出了一个似乎有效的查询 - 这会为你提供所有在计划缓存中引用给定表的sproc名称。您可以将sproc名称与sp_recompile语法连接起来,以生成一堆然后可以执行的sp_recompile语句。

;WITH XMLNAMESPACES (default 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
,TableRefs (SProcName, ReferencedTableName) as
(
    select
        object_name(qp.objectid) as SProcName,
        objNodes.objNode.value('@Database', 'sysname') + '.' + objNodes.objNode.value('@Schema', 'sysname') + '.' + objNodes.objNode.value('@Table', 'sysname') as ReferencedTableName 
    from sys.dm_exec_cached_plans cp
    outer apply sys.dm_exec_sql_text(cp.plan_handle) st
    outer apply sys.dm_exec_query_plan(cp.plan_handle) as qp
    outer apply qp.query_plan.nodes('//Object[@Table]') as objNodes(objNode)
    where cp.cacheobjtype = 'Compiled Plan'
    and cp.objtype = 'Proc'
)
select 
    * 
from TableRefs
where SProcName is not null
    and isnull(ReferencedTableName,'') = '[db].[schema].[table]'

答案 1 :(得分:3)

您可以优先使用sp_recompile并提供刚刚编入索引的表名。所有依赖于该表的proc将从存储的proc缓存中刷新,并在下次执行时“编译”

从msdn docs中看到这个: sp_recompile (Transact-SQL)

答案 2 :(得分:1)

我认为,如果已启用自动生成统计信息选项,那么可能会从相关索引的存在中受益的存储过程将自动生成新的查询计划。

请参阅“重新编译执行计划”一节,了解导致自动重新编译的可能性的详细信息。

http://technet.microsoft.com/en-us/library/ms181055(SQL.90).aspx