从 TPCH 测试学习性能优化技巧之 Q12
一、 查询要求
Q12 语句查询某一年在指定的两种货运模式下,早于交货日期发货而消费者迟于交货日期收到货物的订单中,按货运模式分组统计订单优先级为 URGENT 或 HIGH 的订单数量,以及不是这 2 种优先级的订单的数量。
Q12语句的特点是:带有分组、排序、聚集操作并存的两表连接查询操作。
二、 Oracle执行
Oracle编写的查询SQL语句如下:
select /*+ parallel(n) */
l_shipmode,
sum(case
when o_orderpriority = '1-URGENT'
or o_orderpriority = '2-HIGH'
then 1
else 0
end) as high_line_count,
sum(case
when o_orderpriority <> '1-URGENT'
and o_orderpriority <> '2-HIGH'
then 1
else 0
end) as low_line_count
from
orders,
lineitem
where
o_orderkey = l_orderkey
and l_shipmode in ('TRUCK', 'MAIL')
and l_commitdate < l_receiptdate
and l_shipdate < l_commitdate
and l_receiptdate >= date '1995-01-01'
and l_receiptdate < date '1995-01-01' + interval '1' year
group by
l_shipmode
order by
l_shipmode;
其中/*+ parallel(n) */ 是Oracle的并行查询语法,n是并行数。
脚本执行时间,单位:秒
并行数 |
1 |
2 |
4 |
8 |
12 |
Oracle |
441 |
341 |
264 |
180 |
184 |
三、 SPL优化
这里的orders与lineitem主子表关联优化原理与Q3中类似。
注意到SQL中high_line_count和low_line_count的条件正好相反,其中一个可以被另一个用更简单的计算式计算出来。而且这两个计算列只和orders表相关,可先将其计算出来后再与lineitem做连接,这样比先连接再计算的计算量要少很多,因为orders表要比lineitem表小很多。
SPL脚本如下:
A |
|
1 |
=now() |
2 |
1995-1-1 |
3 |
=elapse@y(A2, 1) |
4 |
=["MAIL", "TRUCK"] |
5 |
=file("orders.ctx").open().cursor@m(O_ORDERKEY,O_ORDERPRIORITY).run(O_ORDERPRIORITY=if(O_ORDERPRIORITY=="1-URGENT" || O_ORDERPRIORITY=="2-HIGH",1,0)) |
6 |
=file("lineitem.ctx").open().news(A5,L_SHIPMODE,L_RECEIPTDATE,L_SHIPDATE,L_COMMITDATE,O_ORDERPRIORITY;L_RECEIPTDATE>=A2 && L_RECEIPTDATE<A3 && A4.contain(L_SHIPMODE)).select( L_COMMITDATE<L_RECEIPTDATE && L_SHIPDATE<L_COMMITDATE) |
7 |
=A6.groups(L_SHIPMODE;sum(O_ORDERPRIORITY):high_line_count, sum(1-O_ORDERPRIORITY):low_line_count) |
8 |
return interval@ms(A1,now()) |
脚本执行时间,单位:秒
并行数 |
1 |
2 |
4 |
8 |
12 |
Oracle |
441 |
341 |
264 |
180 |
184 |
SPL组表 |
200 |
100 |
50 |
28 |
20 |
英文版