我正在使用SQL Server 2008。
我有一个有趣的场景,如果主表中有数据,存储过程(由“超级用户”编写)有一个好的运行时间(大约4秒)。如果搜索值不存在,则运行时间平均为大约3分钟。由于进程的工作方式以及使用该过程的Web应用程序,在没有数据的情况下需要空结果集。
我已经测试了下面的逻辑,其值包含数据和值,但流量似乎无效;但是,当我将我的实际查询放在else语句中时,尽管我知道逻辑分支不应该执行,但似乎总是正在评估该部分。
DECLARE @spId int
SELECT @spId = td.mainId
FROM dbo.PRIMARYTABLE
WHERE td.longId = @searchVal
IF @spId < 1 OR @spId IS NULL
BEGIN
select 'RETURN EMPTY RESULT SET' as test
END
ELSE
BEGIN
SELECT 'DO ACTUAL QUERY' as test
END
当我用虚拟值(例如1111)测试时,返回选择'RETURN EMPTY RESULT SET'作为测试。当我使用我知道存在的值时,将返回SELECT'DO ACTUAL QUERY'作为测试。当我用实际的重载查询替换“SELECT'DO ACTUAL QUERY'作为测试”并使用相同的不存在的虚拟值时,它仍然看起来像是达到了ELSE子句。
我在这里缺少什么?
答案 0 :(得分:1)
也许你没有展示一切。在select中没有返回任何行的分配有一个反直觉的事 - 变量的值不会被清除。将其粘贴在SSMS中:
declare @searchVal as int
set @searchVal=111
DECLARE @spId int
set @spId = 2134
SELECT @spId = td.mainId
FROM (select 839 as mainId, 0 as longid) td
where td.longId = @searchVal
print @spid
@spid将是2134.这就是为什么你应该总是使用@@ rowcount进行测试,在你的情况下
IF @@rowcount = 0 or @spId < 1 or @spId is null
BEGIN
select 'RETURN EMPTY RESULT SET' as test
END
ELSE
BEGIN
SELECT 'DO ACTUAL QUERY' as test
END
longId也有可能存在重复数据,从满足@searchval条件的行返回随机mainid。
除此之外,我不知道。
答案 1 :(得分:0)
谢谢大家的建议。我为缺少发布整个存储过程而道歉,但我不允许分享那些确切的代码。我开始使用的代码段是伪代码(嗯,重命名了表和字段的实际代码)。
我认为NikolaMarkovinović可能会回答他的回答和文章链接。这整个考验都令人发狂。我用谷歌搜索,调试,然后再做一遍,然后搜索堆栈溢出。在你的建议稍作修改之后,程序神奇地开始响应我认为应该的运行时间。我不认为一些初始更改或者可能没有被sql server正确缓存;除了猜测,我什么都没有。
这是非常奇怪的,因为在一个小时或更长的时间里,它一直在运行,好像从未改变过(性能明智)......然后它就开始了。我想知道这不是我的错,也许我没有改变那个关于升级的那个,就像我在测试中做的那个......这似乎是最可行的解释。
无论如何,谢谢你的建议。我学到了一些东西,所以总是很好。