172分
206帖子 Wierd Cmd.ExecuteReader性能问题 23小时,8分钟前|链接
我有以下查询构建:
SELECT TOP 14 DocumentId
FROM idx1_AuthLetters
a INNER JOIN Documents b ON a.DocumentId = b.Id
WHERE Status in ('L','S','V')
AND ServiceCenter = 'NC'
AND mem_name like '%ZZZ%'
ORDER BY DOCUMENTID
当我在Sql Server Management Studio查询窗口中运行它时,它会在一瞬间运行它。很快。
对于此查询,我得到0条记录。
问题是我正在动态构建此查询。 所以如果我在查询执行之前放置一个断点,并检查cmd对象,这就是我所看到的:
SELECT TOP 14 DocumentId
FROM idx1_AuthLetters a
INNER JOIN Documents b ON
a.DocumentId = b.Id
WHERE Status in ('L','S','V')
AND ServiceCenter = @1
AND mem_name like @2
ORDER BY DOCUMENTID
参数值为
@1: NC
@2: %ZZZ%
有趣的是,如果有记录返回,而不是0记录,那么一切正常。
一个例子是使用不同的参数值构建相同的查询:
SELECT TOP 14 DocumentId
FROM idx1_AuthLetters a
INNER JOIN Documents b
ON a.DocumentId = b.Id
WHERE Status in ('L','S','V')
AND ServiceCenter = @1
AND mem_name like @2
ORDER BY DOCUMENTID
@1: NC
@2: %JOHN%
这是最近的一个问题。这两个测试用例对我来说都很好但现在返回了0条记录会导致cmd.ExecuteReader()行超时。
此外,我们在Oracle中遇到了同样的问题。 虽然它没有超时 - 但在Oracle版本中只是有点慢。
此查询在Oracle中返回0条记录需要11秒,而对于包含记录的查询则需要0或1秒。
是什么导致这种情况?
答案 0 :(得分:1)
尝试将OPTION (RECOMPILE)
添加到动态构建的查询中,例如像
SELECT TOP 14 DocumentId
FROM idx1_AuthLetters a
INNER JOIN Documents b
ON a.DocumentId = b.Id
WHERE Status in ('L','S','V')
AND ServiceCenter = @1
AND mem_name like @2
ORDER BY DOCUMENTID
OPTION (RECOMPILE)
这将避免参数嗅探,这通常会导致从.NET代码执行SQL语句/存储过程时性能降低
答案 1 :(得分:0)
在SQL Server Management Studio中,有一项称为执行计划可视化的强大功能。使用执行计划执行查询,您将获得有关如何在服务器上处理查询的(字面)图片。查找带有表扫描的嵌套循环。
这通常是非索引或索引不正确的数据库的问题,但如果没有关于数据库结构的其他信息,我认为没有人可以帮助您正确。
编辑:如果您的问题只发生在从.Net代码访问数据库时,您应该使用SQL Server Profiler(Management Studio - >工具 - > SQL Server Profiler),在您的数据库上启动跟踪,然后运行在您的客户端查询。 Profiler跟踪将显示执行的实际查询(由于params,您可能需要编辑一点),然后将该查询与执行计划一起使用。