Edm*_*und 8 sql-server stored-procedures set-returning-functions
在 SQL Server 数据库sp_recompile
上可以运行一个存储过程来更新执行计划。我想在数据库中的所有存储过程上运行它。另外,我想在所有表值函数上运行它的等效函数,但我不知道要运行哪个 sys 过程。
是否可以在不sp_recompile
为 SQL Server Management Studio 中的所有存储过程名称手动输入一行的情况下执行此操作?同样对于表值函数?
我相信我需要这样做,因为 VM SQL Server 的内存显着增加,但我只看到执行时间略有增加。执行计划显示 80% 以上的运行时间都在聚集索引查找上,所以我认为我可以做更多的事情来优化存储过程。
sp_recompile
如果您认为这会有所帮助,您可以通过使用游标为每个对象生成即席 SQL 并运行它来运行所有内容:
DECLARE C CURSOR FOR (SELECT [name] FROM sys.objects WHERE [type] IN ('P', 'FN', 'IF'));
DECLARE @name SYSNAME;
OPEN C;
FETCH NEXT FROM C INTO @name;
WHILE @@FETCH_STATUS=0 BEGIN
EXEC sp_recompile @name;
FETCH NEXT FROM C INTO @name;
END;
CLOSE C;
DEALLOCATE C;
Run Code Online (Sandbox Code Playgroud)
或者您可以生成 ad-hoc SQL 并通过 运行它EXEC
,需要更少的代码,这可能会稍微提高效率:
DECLARE @sql NVARCHAR(MAX) = '';
SELECT @sql += 'EXEC sp_recompile '''+[name]+''''+CHAR(10) FROM sys.objects WHERE [type] IN ('P', 'FN', 'IF');
EXEC (@sql);
Run Code Online (Sandbox Code Playgroud)
(虽然我发现这种形式有时会因为看起来是基于集合但迭代地构建字符串而不是标准的 SQL 模式而引发人们的注意)
此处可能存在类似问题的另一组对象是视图。您可以类似地将它们标记为需要重新评估,以确保存储的计划和其他元数据不会过时sp_refreshview
,通过对上面显示的游标或临时 SQL 方法进行小的修改:
DECLARE @sql NVARCHAR(MAX) = '';
SELECT @sql += 'EXEC sp_refreshview '''+[name]+''''+CHAR(10) FROM sys.objects WHERE [type] IN ('V');
EXEC (@sql);
Run Code Online (Sandbox Code Playgroud)
执行计划显示 80% 以上的运行时间都在聚集索引查找上,所以我认为我可以做更多的事情来优化存储过程。
有时优化比优先搜索而不是扫描等等更重要,有时索引扫描比多次执行搜索操作更有效,并且计算您正在查看的百分比数字的成本估计是(估计)在最好的(有用的指南,但有时根本不准确)。
虽然“投入更多内存”可以帮助一些数据库性能问题,至少是暂时的,但如果您的瓶颈非常受 CPU 限制而不是内存和/或 IO 限制,那么添加更多内存将几乎没有影响。
该解决方案基于此处的其他答案,但考虑了架构并考虑了名称中的特殊字符。它重新编译所有模式中的 所有过程、函数和内联函数。
create procedure dbo.RecompileAllProcedures
as
begin
declare cur cursor for
(
select quotename(s.name) + '.' + quotename(o.name) as procname
from
sys.objects o
inner join sys.schemas s on o.schema_id = s.schema_id
where o.[type] in ('P', 'FN', 'IF')
);
declare @procname sysname;
open cur;
fetch next from cur into @procname;
while @@fetch_status=0
begin
exec sp_recompile @procname;
fetch next from cur into @procname;
end;
close cur;
deallocate cur;
end;
Run Code Online (Sandbox Code Playgroud)
然后可以按如下方式调用它:
exec dbo.RecompileAllProcedures
Run Code Online (Sandbox Code Playgroud)
PS:我是 Allman 编码风格的忠实粉丝;)
编辑:通过使用更安全的方法改进了程序,quotename
以防名称包含方括号。
如果您添加内存(即使是热添加到虚拟机),并增加最大服务器内存以匹配,您的计划缓存将被清除。
这实际上是“重新编译”您提到的所有这些内容,因为它们在缓存中没有存储的计划可供重复使用。SQL Server 必须构建一个新的。
不过,您可能从未设置过最大服务器内存。如果您对此不确定,可以运行DBCC FREEPROCCACHE
以清除计划缓存。
您在生产中这样做的风险由您自己承担。我不能保证新计划会更好。
内存并不能解决 SQL Server 中的所有性能问题,Seek 也不一定是性能调优的终点线。
如果您需要特定查询的帮助,您应该提出一个单独的问题。
归档时间: |
|
查看次数: |
19251 次 |
最近记录: |