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