我们有一个问题,我们从 ColdFusion 9 调用 SQL Server 2005。我无法发布原始查询,但这不是问题的焦点,我已经发布了导致问题的相关组合。
我们有一个查询,它是以下示例查询的更复杂版本,其中something
列是主键。value 参数没有改变。由于某些我们无法理解的奇怪原因,此查询需要将近 20 秒才能运行....
<cfquery result="q" datasource="dsn">
SELECT something
FROM somewhere
WHERE something = <cfqueryparam cfsqltype="cf_sql_integer" value="#value#"/>
</cfquery>
请注意,如果您突出显示上面源代码的最后一行,cfqueryparam 标记后有一个空格。
以下查询完全不同,我相信您可以自己看到,运行需要 15 毫秒。
<cfquery result="q" datasource="dsn">
SELECT something
FROM somewhere
WHERE something = <cfqueryparam cfsqltype="cf_sql_integer" value="#value#"/>
</cfquery>
cfqueryparam 后面没有空格。但是,在末尾添加两个空格也会产生 15 毫秒。如果我们最后回到一个空格,我们会在大约 20 秒内再次得到结果。
我们检查了 Java 和 SQL Server 之间的数据库驱动程序日志,似乎没有什么异常。这里会发生什么?
编辑
我们在 SQL Server 上运行了分析,它表明对于具有单个空格的查询,它使用的缓存执行计划与具有零个或多个空格的缓存执行计划不同。SQL Server 缓存查询的执行计划。它还使用完整的文字查询作为标识符。因此,当我们发送其他查询时,正在使用不同的执行计划。
更远
其中一个执行计划看起来像是在其中一个子选择上查找不正确的索引,目前尚不清楚 SQL Server 为何决定采用此替代执行计划,或者为什么其中一个索引看起来是错误的。
跟进
对于任何对可能导致错误执行计划的原因感兴趣的人,此处发布了后续问题:SQL Server 2005 cached an execution plan that could never work