我有一个这样的 SQL 查询:
SELECT A, B, (CASE WHEN C=0 THEN 0 ELSE 1 END), COUNT(D)
FROM SomeTable
GROUP BY A, B, (CASE WHEN C=0 THEN 0 ELSE 1 END)
Run Code Online (Sandbox Code Playgroud)
在庞大的数据集上,实际执行计划大部分时间都归因于对应于逻辑操作 Aggregate和物理操作 HashMatch 的节点。
更改列和条件在列表中的GROUP BY
列出顺序会影响性能吗?
我有一个表,对于一组给定的字段 a、b 和 c,我需要获取按 d 和 e 排序的第一行和最后一行,并且正在使用 ROW_NUMBER 来获取这些行。声明的相关部分是...
ROW_NUMBER() OVER (PARTITION BY a,b,c ORDER BY d ASC, e ASC) AS row_number_start,
ROW_NUMBER() OVER (PARTITION BY a,b,c ORDER BY d DESC, e DESC) AS row_number_end
Run Code Online (Sandbox Code Playgroud)
执行计划显示了两个排序操作,每个操作一个。这些排序操作占语句总成本的 60% 以上(我们在这里谈论的是数千万行,分区通常每个分区有 1-100 条记录,大部分在 10 条以下)
所以如果我能摆脱其中的一个就好了。我试图创建一个索引来复制排序;这消除了排序操作之一,但没有消除后者。(请注意,创建的任何索引仅用于此过程,并且会作为 ETL 过程的一部分每天重新创建。)
从检查执行计划来看,我认为问题是在执行partition by语句时,SQL Server坚持按分区列升序排序。从逻辑上讲,是升序还是降序都没有关系,如果优化器理解这一点,那么它可以向后读取相同的索引来计算 row_number_end。
有什么方法可以让优化器在这里看到意义,或者有人可以建议另一种方法来实现相同的最终目标吗?