7

看看这个小提琴: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 。

4

3 回答 3

0

可能这个会起作用

select a.X, a.Y from A a
    cross apply
        (select top 1 * from A t where t.X = a.X order by t.Y asc) as idx

SQLFiddle http://sqlfiddle.com/#!6/a3362/2

于 2012-10-19T16:12:29.197 回答
0

查询确实会产生相同的输出,但在 sql 优化器看来,它们是不同的。本文建议查看OPTION 子句(不幸的是,在 SQL 2005 之前不包括在内)。

您可以在 Entity Framework 之上 Brew Your Own Query,这可能是实现所需性能的最佳选择。

于 2012-10-19T18:00:39.157 回答
0

这是我自己的答案。

最终,我使用了-powered 技巧,通过将这些列转换为恒定长度的字符串表示形式(仔细调整以进行排序)并将这些字符串连接成一个字符串min,我绕过了实际上是几列的事实。Y完成后,我可以使用该连接字符串作为min().

我仍然想知道这样做的正确方法。如果有人碰巧知道,我将不胜感激。

于 2012-10-23T14:34:28.207 回答