为什么针对MSSQL 2008SP2的ODBC查询所需的时间是Studio中相同查询的100倍?

时间:2012-02-08 18:11:24

标签: sql-server database

我有一个非常奇怪的查询,涉及到复杂视图的连接。我分析了视图中的内容,构建了一些索引,并在从MSSQL Management Studio运行时使查询工作在一秒钟内。但是,当从Perl通过ODBC运行时,完全相同的查询大约需要80秒才能返回。

我已经倾倒了近8个小时,它继续让我感到困惑。在那段时间我从Perl中记录了查询并将其逐字复制到Studio中,我将它包装在一个存储过程中(这使得它与BOTH客户端保持一致的2.5分钟!),我用Google搜索了ODBC& MSSQL查询缓存,我看过通过Activity Monitor运行的查询(它大部分时间都在通用的SLEEP_TASK等待状态下运行)和Profiler(select语句得到一行,直到它完成运行才显示),我已经开始阅读性能瓶颈了。

我没有注意到来自Perl的任何其他查询的这个问题,不幸的是我们没有现场的DBA。我是一名做过DBA的程序员,但我觉得我在这个黑暗中摸索着。我最好的猜测是,Studio提供的某种查询缓存是ODBC客户端无法访问的,但重新启动Studio不会使查询的第一次执行需要更长的时间,因此它看起来不像是因为每个新的ODBC连接以空缓存开头。

不进入视图定义,基本查询非常简单:

SELECT * FROM VIEW1 LEFT OUTER JOIN VIEW2 WHERE SECTION = ? AND ID = ?

当我丢弃VIEW2时,延迟消失,但我需要该视图中的数据。为了简化和提高效率,我已经三次重写了视图,但由于查询从Studio运行良好,这感觉有点像死路一条。查询只返回一行,但即使删除ID条件并为整个部分选择所有56k行,也只需要40秒。还有其他想法吗?

编辑2/8: @Remus Rusanu的文章非常清楚,但我担心它并不适用。现在看来很清楚它根本不是ODBC,但是当我硬编码参数而不是参数化它们时,我会得到不同的执行计划。我可以在SSMS中重现这个:

SELECT * FROM VIEW1 LEFT OUTER JOIN VIEW2 WHERE SECTION = 'a' AND ID = 'b'

快100倍
DECLARE @p1 VARCHAR(8), @p2 VARCHAR(3)
SET @p1 = 'a'
SET @p2 = 'b'
SELECT * FROM VIEW1 LEFT OUTER JOIN VIEW2 WHERE SECTION = @p1 AND ID = @p2

不幸的是,我仍然无法解释为什么第一个应该得到的执行计划比参数化版本的时间少两个数量级,因为SECTION&的任何值都是如此。 ID我可以扔掉它。它可能是SQL Server的一个缺陷,但只是看起来很愚蠢,输入在两个地方都是已知的,但是这个输入需要更长的时间。如果SQL Server每次都从头开始重新计算参数化计划,因为它必须对我提供的不同常量值进行重复计算,它将快100倍。本文建议的RECOMPILE选项似乎都没有帮助。

我认为@GSerg在下面称它。我还没有证明在视图外部使用的窗口函数不会发生这种情况,但是他描述了同样的事情,时间差异仍然令人困惑。

如果我没有时间去研究这个问题,我会尝试调整一些文章的建议并强制执行参数化版本的持续执行计划,但它看起来应该是很多不必要的麻烦。

3 个答案:

答案 0 :(得分:3)

explainedMartin Smith,它是SQL Server中的issue with predicate pushing,尚未完整修复。

如相关问题的答案和评论中所述,您可以

  • 将查询包装为附加option(recompile)
  • 的内容
  • 将其转换为表值函数。
  • Attach a plan guideoption (recompile)

答案 1 :(得分:1)

您想知道的有关此主题的所有内容:Slow in the Application, Fast in SSMS? Understanding Performance Mysteries

SSMS中没有ODBC无法访问的“缓存”。只是因为参数嗅探或数据类型优先规则导致您在SSMS与ODBC中获得不同的执行计划。阅读链接的文章,它既有识别问题的方法,也有解决方法的建议。

答案 2 :(得分:1)

比较两个查询的计划并检查每个连接的SET设置(您可以通过查看sys.dm_exec_sessions来执行此操作)。我打赌你会看到quoted_identifier,ansi_nulls或arithabort(或者可能全部三个)的区别。这通常会导致执行计划的巨大差异。您应该能够在ODBC版本中手动设置这些设置,以匹配Management Studio正在使用的设置。

一些相关的问题 - 您可能需要检查其他不明显的情况:

SQL Query slow in .NET application but instantaneous in SQL Server Management Studio

SQL Server Query Slow from PHP, but FAST from SQL Mgt Studio - WHY?

Query times out from web app but runs fine from management studio

SQL Server 2005 stored procedure fast in SSMS slow from VBA