从 TPCH 测试学习性能优化技巧之 Q12

一、     查询要求

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优化

这里的orderslineitem主子表关联优化原理与Q3中类似。

注意到SQLhigh_line_countlow_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