一、 查询要求
Q12语句查询获得货运模式和订单优先级。可以帮助决策:选择便宜的货运模式是否会导致消费者更多的在合同日期之后收到货物,而对紧急优先命令产生负面影响。
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=1
2=now()
3>date=date("1995-01-01")
4>shipmode1="TRUCK"
5>shipmode2="MAIL"
6=elapse@y(date, 1)
7=file(path+"orders.ctx").create().cursor@m(O_ORDERKEY,O_ORDERPRIORITY;;A1).run(O_ORDERPRIORITY=if(O_ORDERPRIORITY == "1-URGENT" || O_ORDERPRIORITY == "2-HIGH",1,0))
8=file(path+"lineitem.ctx").create().news(A7,L_ORDERKEY,L_SHIPDATE,L_COMMITDATE,L_RECEIPTDATE,L_SHIPMODE,O_ORDERPRIORITY;(L_SHIPMODE == shipmode1 || L_SHIPMODE == shipmode2) && L_COMMITDATE < L_RECEIPTDATE && L_SHIPDATE < L_COMMITDATE && L_RECEIPTDATE >= date && L_RECEIPTDATE < A6)
9=A8.groups(L_SHIPMODE;sum(O_ORDERPRIORITY):high_line_count, sum(1-O_ORDERPRIORITY):low_line_count)
10=now()
11=interval@s(A2,A10)
脚本执行时间,单位:秒
并行数 1 2 4 8 12
Oracle 441 341 264 180 184
SPL组表 200 100 50 28 20