SQL 提速:大数据表上的多种分组统计
【摘要】
从原理上分析 SQL 语句慢的原因,用代码示例给出提速办法。点击了解SQL 提速:大数据表上的多种分组统计
问题描述
对数据表做分组汇总时要全表遍历。如果要做 n 种不同的分组,就要对数据表遍历 n 次,而大数据的性能瓶颈常常在 IO 上,当表很大时就会消耗很多时间在外存访问上。
例如下面的三种分组方式,对应三个 SQL:
select sum(x) from T group by a,b
select max(y) from T group by c,d
select avg(y),min(z) from T group by a,c
即使用 union 把三个 SQL 合并成一个,也还是要对 T 表遍历三次。
提速方案
如果我们可以在一次遍历中同时计算多种分组汇总,就可以减少外存访问量来提速,也就是复用遍历中读出来的数据。
大数据的分组汇总通常使用游标实现,在用游标遍历时,将读出的每一段数据分组汇总后累积到结果集上。有多种分组,也只要分别分组汇总后累积到各自的结果集上即可。这样,只要遍历一次,就可以得到多种分组结果了。
代码示例
A |
B |
|
1 |
=file("T1.ctx").open() |
|
2 |
=A1.cursor(a,b,c,d,x,y,z) |
|
3 |
cursor A2 |
=A3.groups(a,b;sum(x)) |
4 |
cursor |
=A4.groups(c,d;max(y)) |
5 |
cursor |
=A5.groupx(a,c;avg(y),min(z)) |
6 |
A1:打开组表。
A2:建立游标,准备取出多种分组汇总需要的字段。
A3:用 cursor 关键字定义游标 A2 同步的管道。B3 在管道 A3 设置了第 1 种方式的分组汇总。
同样,A4、A5 又定义了两个管道,B4、B5 定义了相应的第 2、3 种方式的分组汇总。
A6:所有的 cursor 语句或代码块都执行后,SPL 认为整套管道定义结束,就会开始遍历游标,每次读出的数据都会分别送给三个管道,计算三种不同方式的分组汇总。遍历结束后,每个管道计算结果存放在 cursor 语句所在的格中。
管道 A5 与前两个管道不同的是,其分组结果集较大,采用外存大分组算法,所以 A5 单元格计算的结果是大分组返回的游标。
英文版