当使用窗口函数并且谓词包含变量时,SQL Server 使用扫描而不是搜索

标签 sql sql-server performance

看看这个 fiddle :http://sqlfiddle.com/#!6/18324/2

展开第一个执行计划,用于针对 View B 的查询.
请注意,第一个查询使用索引查找执行,而第二个查询 - 使用索引扫描。在我的实际设置中,有数千行,这会产生相当可观的性能损失。

卧槽???

查询是等价的,不是吗?为什么文字会产生搜索和变量扫描?
但更重要的是:我该如何解决这个问题 ?

This post最接近问题,从那里开始工作的解决方案是使用 option(recompile) (谢谢你,马丁史密斯)。但是,这对我不起作用,因为我的查询是由我的 ORM 库(即 Entity Framework )生成的,我无法手动修改它们。
相反,我正在寻找的是一种重新制定 B 的方法。查看,以免出现问题。

在摆弄这个问题的同时,我注意到丢失谓词的总是执行计划中的“段”块。为了验证这一点,我用 min 根据子查询重新构造了查询。功能(见 View D)。瞧! - 针对 D 的两个查询 View 产生相同的计划。

然而,坏消息是我不能使用这个 min - 强力技巧,因为在我的真实设置中,列 Y实际上是 几列 ,以便我可以通过他们订购,但我不能接受 min()其中。
所以第二个问题是:谁能想出一个类似于最小驱动子查询的技巧,但适用于多列?

注 1 : 这个肯定和引爆点没有关系,因为表里只有2条记录。
注释 2 :它也与 View 的存在无关。查看带有 View 的示例 C :在这种情况下,服务器很乐意使用seek。

最佳答案

可能这个会起作用

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

关于当使用窗口函数并且谓词包含变量时,SQL Server 使用扫描而不是搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12976486/

相关文章:

mysql - 从 MySQL 表中删除部分重复项

sql - 如何在连接查询中合并两列?

javascript - 对 d3 树中最右/最左表兄弟节点的最有效访问

SQL 服务器 : impact of column collation on T-SQL instructions

Python: "except KeyError"比 "if key in dict"快吗?

java - 在 Java 中更快地 ping 服务器?

sql - 如何在 BigQuery 中复制开始日期和结束日期之间生成日期的行?

sql - 将一个表中的不同值插入到另一表中

sql - 删除 SQL Server 字段末尾的隐藏字符

sql-server - Docker-compose MS SQL attach_dbs