假设我在表中有以下整数值
32
11
15
123
55
54
23
43
44
44
56
23
OK,列表可以继续;没关系。现在我想查询这个表,我想返回一定数量的closest records
. 假设我想将 10 个最接近的记录匹配返回到数字 32。我可以有效地实现这一点吗?
它位于 SQL Server 2014 中。
假设我在表中有以下整数值
32
11
15
123
55
54
23
43
44
44
56
23
OK,列表可以继续;没关系。现在我想查询这个表,我想返回一定数量的closest records
. 假设我想将 10 个最接近的记录匹配返回到数字 32。我可以有效地实现这一点吗?
它位于 SQL Server 2014 中。
假设列被索引,以下应该是相当有效的。
两次查找 10 行,然后返回(最多)20 行。
(即可能类似于以下内容)
或另一种可能性(将排序的行数减少到最大 10)
注意:上面的执行计划是针对简单的表定义
从技术上讲,也不应该需要底部分支上的排序,因为它也是由 Diff 排序的,并且可以合并两个排序的结果。但我没能得到那个计划。
查询有
ORDER BY Diff ASC, YourCol ASC
,而不仅仅是ORDER BY YourCol ASC
,因为这就是最终摆脱计划顶部分支中的排序的原因。我需要在其中添加辅助列(即使它永远不会改变结果,因为YourCol
对于具有相同 Diff 的所有值都是相同的),因此它将通过合并连接(连接)而不添加排序。SQL Server 似乎能够推断在 X 上按升序搜索的索引将提供按 X + Y 排序的行,并且不需要排序。但是它不能推断出以降序遍历索引会以与 YX 相同的顺序传递行(或者甚至只是一元减 X)。计划的两个分支都使用索引来避免排序,但
TOP 10
底部分支中的然后按Diff
(即使它们已经按该顺序)排序,以使它们按所需的顺序进行合并。对于其他查询/表定义,仅使用一种分支来获取合并计划可能会更棘手或不可能 - 因为它依赖于查找 SQL Server 的排序表达式:
TOP
我有点困惑和惊讶,在这种情况下我们必须做 Union。以下更简单更高效
以下是比较两个查询的完整代码和执行计划
Martin 的第二个建议的细化: