提高 SUM 查询的性能

Mik*_*son 4 sql-server sql-server-2012

我有一个聚合查询,它有很多列并生成一个巨大的数据集:

SELECT      column1,
            column2,
            ...
            column20,
            sum(column21),
            ...
            sum(column40)
INTO        #Output
FROM        #Ledger
GROUP BY    column1,
            ...
            column20
Run Code Online (Sandbox Code Playgroud)

输入表 ( #Ledger) 有 18m 行,结果表 ( #Output) 有 600k 行。查询耗时 9 分钟。有什么我可以做的让它更快吗?这是执行计划:

执行计划

#Ledger表上没有索引,Sort 中的感叹号给出以下警告:

操作员在溢出级别 1 和 4 溢出线程的执行期间使用 tempdb 溢出数据,Sort 将 1541592 个页面写入 tempdb 并从 tempdb 读取 1541592 个页面,授予内存 3752160KB,已用内存 3681824KB

Eri*_*ing 11

查看您的查询计划,优化器似乎选择了一个 Stream Aggregate 运算符来处理您的GROUP BY. 这些的缺点是它们需要有序数据,而 HEAP 不是。

大卫的建议是完全有效的。添加聚集索引可能会删除 Sort 运算符,因此与我的建议相比的性能测试取决于您。

如果索引临时表不能提供您需要的性能,OPTION(HASH GROUP);对查询应用提示将影响优化器使用哈希匹配聚合而不是流聚合。

哈希匹配聚合不需要排序的数据,但也可能像流聚合计划中的 Sort 溢出那样溢出到磁盘。


Dav*_*oft 6

删除不必要的 GROUP BY 列并在剩余的列上创建聚集索引。

这些 GROUP BY 列的哪些子集是唯一标识 #OUTPUT 中的行所必需的?保留那些,并替换其他。就像是:

SELECT      column1,
            column2,
            column3,
            column4,
            max(column5) column5,
            ...
            max(column20) column20,
            sum(column21),
            ...
            sum(column40)
INTO        #Output
FROM        #Ledger
GROUP BY    column1,
            column2,
            column3,
            column4
Run Code Online (Sandbox Code Playgroud)