看看这个小提琴:http ://sqlfiddle.com/#!6/18324/2
展开第一个执行计划,用于针对 view 的查询B
。
请注意,第一个查询使用索引查找执行,而第二个查询使用索引扫描。在我的实际设置中,有数千行,这会产生相当大的性能影响。
怎么回事???
查询是等效的,不是吗?为什么文字会产生搜索和变量扫描?
但更重要的是:我该如何解决这个问题?
这篇文章最接近问题,并且从那里有效的解决方案是使用option(recompile)
(谢谢你,马丁史密斯)。但是,这对我不起作用,因为我的查询是由我的 ORM 库(即实体框架)生成的,我无法手动修改它们。
相反,我正在寻找的是一种重新制定B
视图的方法,这样问题就不会发生。
在摆弄这个问题时,我注意到丢失谓词的总是执行计划中的“段”块。为了验证这一点,我根据带有函数的子查询重新构造了查询min
(参见视图D
)。瞧!- 针对D
视图的两个查询都会产生相同的计划。
然而,坏消息是我不能使用这个min
-powered 技巧,因为在我的实际设置中,该列Y
实际上是几个 columns,所以我可以按它们排序,但我不能接受min()
它们。
所以第二个问题是:任何人都可以想出一个类似于 min-powered 子查询但适用于多个列的技巧吗?
注意 1:这绝对与临界点无关,因为表中只有 2 条记录。
注意 2:它也与视图的存在无关。查看一个带有 view 的示例C
:在这种情况下,服务器很乐意使用 seek 。