性能优化技巧:附表
一、 问题背景与适用场景在《性能优化技巧:有序归并》中我们见证了有序归并算法提升主子表的关联性能,在集算器中,还有进一步提高性能的办法—附表。集算器组表支持主子表保存在同一文件中,先用主表创建组表文件,再在主表上附加上子表,子表必须含有主表的维字段,并通过这个字段进行关联,这样的子表称为附表。附表在存储时,关联键只需在主表保存一次,子表就不用保存了,在读取时就可以减少读硬盘的时间。并且子表已经通过关联键附加在主表记录上了,相当于已经预先关联好了,和有序归并关联相比,就可以减少关联时的比对运算,从而提高关联性能。下面我们就用实例来对比测试一下集算器附表与有序归并的关联性能。二、 测试环境测试机有两个Intel2670 CPU,主频2.6G,共16核,内存64G,SSD固态硬盘。采用TPCH标准生成的200G数据,主表是orders,子表是lineitem。两表中记录分别按O_ORDERKEY、L_ORDERKEY升序排列。三、 附表生成从以前测试用的组表文件orders.ctx和lineitem.ctx中读取数据来生成附表文件,编写SPL脚本如下:
A1=file(path+"orders.ctx").create().cursor()2=file(path+"lineitem.ctx").create().cursor(L_ORDERKEY:O_ORDERKEY, L_LINENUMBER, L_PARTKEY,L_SUPPKEY, L_QUANTITY,L_EXTENDEDPRICE,L_DISCOUNT, L_TAX, L_RETURNFLAG,L_LINESTATUS,L_SHIPDATE, L_COMMITDATE, L_RECEIPTDATE,L_SHIPINSTRUCT, L_SHIPMODE)3=file(path+"orders_lineitem.ctx").create( #O_ORDERKEY,O_CUSTKEY,O_ORDERSTATUS,O_TOTALPRICE, O_ORDERDATE,O_ORDERPRIORITY,O_SHIPPRIORITY)4=A3.attach(lineitem, #L_LINENUMBER, L_PARTKEY,L_SUPPKEY, L_QUANTITY,L_EXTENDEDPRICE,L_DISCOUNT, L_TAX, L_RETURNFLAG,L_LINESTATUS,L_SHIPDATE, L_COMMITDATE, L_RECEIPTDATE,L_SHIPINSTRUCT, L_SHIPMODE)5=A3.append@i(A1)6=A4.append@i(A2)用主表.attach(子表,…)来建立主子表间的依附关系。四、 测试编写有序归并测试的SPL脚本如下:
A112=now()3=file(path+"orders.ctx").create().cursor@m(O_ORDERKEY,O_ORDERDATE;;A1)4=file(path+"lineitem.ctx").create().cursor(L_ORDERKEY,L_EXTENDEDPRICE,L_DISCOUNT;;A3)5=joinx(A4:detail,L_ORDERKEY;A3:orders,O_ORDERKEY)6=A5.groups(year(orders.O_ORDERDATE):l_year; sum(detail.L_EXTENDEDPRICE * (1 - detail.L_DISCOUNT)):revenue)7=interval@s(A2,now())A1单元格是测试并行数。编写附表测试的SPL脚本如下:
A112=now()3=file(path+"orders_lineitem.ctx").create()4=A3.attach(lineitem)5=A4.cursor@m(L_EXTENDEDPRICE,L_DISCOUNT,O_ORDERDATE;;A1)6=A5.groups(year(O_ORDERDATE):l_year; sum(L_EXTENDEDPRICE * (1 - L_DISCOUNT)):revenue)7=interval@s(A2,now())测试结果列表如下(单位:秒):并行数124816附表4272181166246有序归并6753611719264五、 结论从测试结果可以看出,在各种并行线程下,用附表测试的运行时间只有有序归并的60%多,确实可以较大地提高主子表关联性能。另据其它测试表明,由于主子表是1:N的关系,当N越大时或者主表主键是多字段时,就越能减少读硬盘的时间和关联时的比对时间,性能提高就越明显。