1

172 分

206 个帖子 Wierd Cmd.ExecuteReader 性能问题 23 小时 8 分钟前|LINK

我有以下查询:

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 秒。

什么可能导致这种情况?

4

2 回答 2

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 语句/存储过程时导致性能下降的原因

于 2013-07-24T13:27:48.997 回答
0

在 SQL Server Management Studio 中有一个很棒的功能,称为执行计划可视化。使用执行计划执行您的查询,您将获得关于您的查询在服务器上如何处理的(字面)图片。查找带有表扫描的嵌套循环。

这通常是未索引或索引不正确的数据库的问题,但是如果没有有关数据库结构的其他信息,我认为没有人可以正确地帮助您。

编辑:如果您的问题仅在您从 .Net 代码访问数据库时发生,您应该使用 SQL Server Profiler(Management Studio -> 工具 -> SQL Server Profiler),在您的数据库上启动跟踪,然后在您的客户端中运行查询。Profiler 跟踪将显示实际执行的查询(由于参数的原因,您可能需要进行一些编辑),然后将该查询与执行计划一起使用。

于 2013-07-24T13:20:39.843 回答