【发布时间】:2016-08-16 23:05:01
【问题描述】:
我有一个存储过程,它可以从 2 个不同的来源获取数据,具体取决于用户是从单个关闭期间(存档到数据仓库表中)还是从开放期间(来自事务表的数据)请求数据。
如果我将限制选择的参数传递给数据仓库表(为关闭期间提供年份和期间),则该过程需要很长时间才能返回结果,除非我注释掉 ELSE BEGIN... 代码。没有数据来自代码的 ELSE 部分,但它仍在减慢该过程。如果我注释掉代码的 ELSE 部分,它会非常快。
我已经尝试过OPTION (RECOMPILE),并且我正在使用局部变量来避免参数嗅探,但这并没有帮助。有没有办法解决这个问题?
以下是我正在执行的运行缓慢的示例:
IF @Year <> 0 AND @Period <> 0 AND (SELECT PerClosedTimestamp
FROM Period
WHERE
PerCompanyID = @CompanyID AND
PerYear = @Year AND
PerPeriod = @Period) IS NOT NULL
BEGIN
SELECT
datawhse.column1, datawhse.column2, etc …
FROM
datawhse
END
ELSE
BEGIN
SELECT
trantable.column1, trantable.column2, etc…
FROM
trantable
END
如果我排除 ELSE 语句,它会运行得非常快:
IF @Year <> 0
AND @Period <> 0
AND (SELECT PerClosedTimestamp
FROM Period
WHERE PerCompanyID = @CompanyID
AND PerYear = @Year
AND PerPeriod = @Period) IS NOT NULL
BEGIN
SELECT datawhse.column1
,datawhse.column2, etc …
FROM datawhse
END
【问题讨论】:
-
不是一个答案,而是一个有趣的相关(不重复)帖子dba.stackexchange.com/questions/9835/…
-
如果在“PerClosedTimestamp”前面添加TOP 1 或使用EXISTS 会怎样。还尝试将条件更改为 IF Year = 0 或 Period = 0 或 (select...) 为空,然后执行第二个块,否则执行第一个块。尝试将“WHERE Year = 0 or Period = 0”(通过复制条件)放入第二个块。
-
很高兴看到慢速和快速执行的查询计划。
-
寻求性能帮助的问题,应添加表架构、执行计划、涉及的表数和重现的最少步骤..
-
您可以将 2 个选择拆分为存储过程;那么每个人都会得到一个更适合的查询计划。 (刚刚意识到这是一个老问题!)
标签: sql-server performance if-statement stored-procedures