问题描述
|
我们的应用程序发出NHibernate生成的SQL查询。在应用程序运行时,对SQL Server数据库运行查询大约需要12秒钟。 SQL Profiler显示超过500,000次读取。
但是,如果我使用SQL事件探查器捕获确切的查询文本,然后从SQL Studio中再次运行它,则需要5秒钟并且显示少于4,600次读取。
该查询使用了几个参数,这些参数的值在SQL文本的末尾提供,并且我读了一些有关参数嗅探和效率低下的查询计划的信息,但我认为这与存储过程有关。也许NHibernate在实例化其实体时将结果集保持打开状态,这可以解释较长的持续时间,但是对于与NHibernate执行的相同查询,可以解释额外的494,000个“读取”吗? (SQL Profiler跟踪中没有其他查询。)
该查询使用NHibernate 3.1的LINQ工具指定为LINQ查询。我之所以没有包含查询本身,是因为这似乎是一个基本的哲学问题:是什么可以解释如此巨大的差异?
如果需要的话,结果中也会有一个varbinary(max)列,但在我们的情况下,它始终包含null。
非常感谢任何见解!
解决方法
请务必阅读:http://www.sommarskog.se/query-plan-mysteries.html
proc和sp_executesql适用相同的规则。伪劣计划的一个巨大原因可能是在
varchar
字段中传递ѭ0,参数,这导致索引扫描而不是寻道。
我非常怀疑输出是否会影响此处的性能,这可能与传入的参数之一或基础表的选择性有关。
测试探查器的输出时,请确保包括sp_executesql
,并确保您的设置匹配(诸如ѭ3st之类的东西),否则您将导致生成新计划。
您始终可以通过sys.dm_exec_query_stats
从执行缓存中提取伪劣计划。