我有一个SQL Server存储过程,其中包含以下T-SQL代码:
insert into #results ([ID], [Action], [Success], [StartTime], [EndTime], [Process])
select
'ID' = aa.[ActionID],
'Action' = cast(aa.[Action] as int),
'Success' = aa.[Success],
'StartTime' = aa.[StartTime],
'EndTime' = aa.[EndTime],
'Process' = cast(aa.[Process] as int)
from
[ApplicationActions] aa with(nolock)
where
0 = case
when (@loggingLevel = 0) then 0
when (@loggingLevel = 1 and aa.[LoggingLevel] = 1) then 0
end
and
1 = case
when (@applicationID is null) then 1
when (@applicationID is not null and aa.[ApplicationID] = @applicationID) then 1
end
and
2 = case
when (@startDate is null) then 2
when (@startDate is not null and aa.[StartTime] >= @startDate) then 2
end
and
3 = case
when (@endDate is null) then 3
when (@endDate is not null and aa.[StartTime] <= @endDate) then 3
end
and
4 = case
when (@success is null) then 4
when (@success is not null and aa.[Success] = @success) then 4
end
and
5 = case
when (@process is null) then 5
when (@process is not null and aa.[Process] = @process) then 5
end
这是困扰我的“动态”WHERE子句。用户不必将每个参数传递给此存储过程。只是他们有兴趣用作输出过滤器的那些。
如何使用SQL Server Studio或Profiler测试此存储过程是否每次都重新编译?
答案 0 :(得分:1)
只是随便,您可以简化这些:
2 = case
when (@startDate is null) then 2
when (@startDate is not null and aa.[StartTime] >= @startDate) then 2
end
到此:
(@startDate is null OR aa.[StartTime] >= @startDate)
就重新编译而言 - 它是否声明为WITH RECOMPILE
?
答案 1 :(得分:1)
以下文章介绍了如何确定存储过程是否正在重新编译: http://it.toolbox.com/blogs/programming-life/sql-performance-abnormal-stored-procedure-recompiles-8105
以下是相应部分的引用:
启动SQL事件探查器并启动新的 跟踪,连接到我们的服务器并给予 一个合适的跟踪名称,选择 事件选项卡并删除已经 “选定活动”上的现有活动 类“列表框。现在选择 “存储过程”节点中的 “可用的事件类”并添加 SPComplete,SPRecompile,SPStarting, SP:StmtStarting和SP:StmtCompleted。 现在选择“数据列”选项卡和 选择恰到好处的数量 您需要的事件和数据列。 添加过滤器以减少数量 你收集的事件。
我会按存储过程的名称进行过滤。
答案 2 :(得分:1)
您插入示例中的临时表,导致每次都重新编译SP,因为它无法预编译。
这是使用临时表和表变量之间的差异之一 - 可以找到关于差异的好文章here
相关提取物......
第二个主要区别是 任何带临时表的过程 不能预先编译,而一个 执行计划的程序 表变量可以是静态的 事先编译。预编译a 脚本给它带来了一个主要优势 执行速度。这个优势可以 对于漫长的程序来说是戏剧性的 重新编译可能过于昂贵。