其他
性能优化技巧:维表过滤或计算时的关联
1. 预关联
A | |
1 | >customer=file("/home/ctx/customer.ctx").open().memory().keys@i(C_CUSTKEY) |
2 | >orders=file("/home/ctx/orders.ctx").open().memory() |
3 | =orders.switch(O_CUSTKEY,customer) |
4 | =now() |
5 | =orders.select(left(O_CUSTKEY.C_NAME,4)!="shen" && O_CUSTKEY.C_NATIONKEY>-1 && O_CUSTKEY.C_ACCTBAL>bal) |
6 | =A5.sum(O_TOTALPRICE) |
7 | =interval@s(A4,now()) |
A1中读入维表并创建索引,A2中读入事实表,A3中进行预关联,这些时间都不计入测试时间,从A4才开始计时。
2. 重建索引
A | |
1 | >customer=file("/home/ctx/customer.ctx").open().memory().keys@i(C_CUSTKEY) |
2 | >orders=file("/home/ctx/orders.ctx").open().memory() |
3 | =now() |
4 | =customer.select(left(C_NAME,4)!="shen" && C_NATIONKEY>-1 && C_ACCTBAL>bal).derive@o().keys@i(C_CUSTKEY) |
5 | =orders.switch@i(O_CUSTKEY,A4) |
6 | =A5.sum(O_TOTALPRICE) |
7 | =interval@s(A3,now()) |
A4中customer过滤后再重建索引,A5中进行关联。
3. 复用索引
4. 外键序号化
A | |
1 | >customer=file("/home/ctx/customer_xh.ctx").open().memory() |
2 | >orders=file("/home/ctx/orders_xh.ctx").open().memory() |
3 | =now() |
4 | =orders.switch@i(O_CUSTKEY,customer:#) |
5 | =A4.select(left(O_CUSTKEY.C_NAME,4)!="shen" && O_CUSTKEY.C_NATIONKEY>-1 && O_CUSTKEY.C_ACCTBAL>bal) |
6 | =A5.sum(O_TOTALPRICE) |
7 | =interval@s(A3,now()) |
序号化关联不需要索引,所以A1中不创建索引。A4中用customer:#表示用O_CUSTKEY的值与customer的行号关联。
5. 序号化后对位序列
A | |
1 | >customer=file("/home/ctx/customer_xh.ctx").open().memory() |
2 | >orders=file("/home/ctx/orders_xh.ctx").open().memory() |
3 | =now() |
4 | =customer.(left(C_NAME,4)!="shen" && C_NATIONKEY>-1 && C_ACCTBAL>bal) |
5 | =orders.select(A4(O_CUSTKEY)) |
6 | =A5.sum(O_TOTALPRICE) |
7 | =interval@s(A3,now()) |
在A4中用customer.(过滤条件) 算出一个与记录数等长的、值为true或false的序列,我们称之为对位序列;orders表中的O_CUSTKEY已经序号化处理过,它的值对应于customer的记录行号,所以在A5就可以用A4(O_CUSTKEY)来判断orders中此行数据是否满足过滤条件。
6. 测试结果与分析
维表过滤后记录数 | 716万 | 613万 | 477万 | 273万 | 68万 |
预关联 | 41 | 39 | 38 | 37 | 35 |
重建索引 | 39 | 34 | 29 | 25 | 19 |
复用索引 | 35 | 31 | 27 | 23 | 17 |
外键序号化 | 53 | 51 | 49 | 48 | 46 |
对位序列 | 25 | 23 | 21 | 19 | 16 |
这个实验中,维表数据记录750万行,事实表orders数据记录7500万行,是维表的10倍。
1. 关联后再过滤
A | |
1 | >orders=file("/home/ctx/orders.ctx").open().memory().keys@i(O_ORDERKEY) |
2 | =now() |
3 | =file("/home/ctx/lineitem.ctx").open().cursor(L_ORDERKEY,L_EXTENDEDPRICE) |
4 | =A3.switch@i(L_ORDERKEY,orders) |
5 | =A4.select(left(L_ORDERKEY.O_ORDERPRIORITY,2)!="9-" && L_ORDERKEY.O_ORDERSTATUS!="A" && L_ORDERKEY.O_ORDERDATE>date("1990-01-01") && L_ORDERKEY.O_TOTALPRICE>price) |
6 | =A5.total(sum(L_EXTENDEDPRICE)) |
7 | =interval@s(A2,now()) |
由于事实表很大,使用游标读取数据,并与维表关联后再过滤。
2. 重建索引
编写SPL脚本如下:
A | |
1 | >orders=file("/home/ctx/orders.ctx").open().memory().keys@i(O_ORDERKEY) |
2 | =now() |
3 | =orders.select(left(O_ORDERPRIORITY,2)!="9-" && O_ORDERSTATUS!="A" && O_ORDERDATE>date("1990-01-01") && O_TOTALPRICE>price).derive@o().keys@i(O_ORDERKEY) |
4 | =file("/home/ctx/lineitem.ctx").open().cursor(L_ORDERKEY,L_EXTENDEDPRICE).switch@i(L_ORDERKEY,A3) |
5 | =A4.total(sum(L_EXTENDEDPRICE)) |
6 | =interval@s(A2,now()) |
A3中orders过滤后再重建索引。
3. 复用索引
4. 外键序号化
A | |
1 | >orders=file("/home/ctx/orders_xh.ctx").open().memory() |
2 | =now() |
3 | =file("/home/ctx/lineitem_xh.ctx").open().cursor(L_ORDERKEY,L_EXTENDEDPRICE) |
4 | =A3.switch@i(L_ORDERKEY,orders:#) |
5 | =A4.select(left(L_ORDERKEY.O_ORDERPRIORITY,2)!="9-" && L_ORDERKEY.O_ORDERSTATUS!="A" && L_ORDERKEY.O_ORDERDATE>date("1990-01-01") && L_ORDERKEY.O_TOTALPRICE>price) |
6 | =A5.total(sum(L_EXTENDEDPRICE)) |
7 | =interval@s(A2,now()) |
A4中用orders:#表示用L_ORDERKEY的值与orders的行号关联。
5. 序号化后对位序列
A | |
1 | >orders=file("/home/ctx/orders_xh.ctx").open().memory() |
2 | =now() |
3 | =orders.(left(O_ORDERPRIORITY,2)!="9-" && O_ORDERSTATUS!="A" && O_ORDERDATE>date("1990-01-01") && O_TOTALPRICE>price) |
4 | =file("/home/ctx/lineitem_xh.ctx").open().cursor(L_ORDERKEY,L_EXTENDEDPRICE).select(A3(L_ORDERKEY)) |
5 | =A4.total(sum(L_EXTENDEDPRICE)) |
6 | =interval@s(A2,now()) |
查询实现原理与全内存时相同。
6. 测试结果与分析
维表过滤后记录数 | 6443万 | 4995万 | 3590万 | 2249万 | 428万 |
关联后过滤 | 101 | 98 | 97 | 94 | 92 |
重建索引 | 102 | 98 | 92 | 73 | 53 |
复用索引 | 85 | 82 | 77 | 74 | 57 |
外键序号化 | 79 | 78 | 76 | 75 | 72 |
对位序列 | 53 | 49 | 47 | 43 | 39 |
这个实验中,维表数据记录7500万行,事实表lineitem数据记录3亿行,是维表的4倍。
1) 如果数据表做了序号化处理,采用对位序列技术。
1) 如果数据表做了序号化处理,采用对位序列技术。
更多性能优化技巧,可在底部“阅读原文”中查看
重磅!开源SPL交流群成立了
简单好用的SPL开源啦!
为了给感兴趣的小伙伴们提供一个相互交流的平台,
特地开通了交流群(群完全免费,不广告不卖课)
需要进群的朋友,可长按扫描下方二维码
本文感兴趣的朋友,请转到阅读原文去收藏 ^_^