陈焕生:深入理解陈焕生:深入理解Oracle的并行执行的并行执行(三三)
Partition Wise Join,消除分发的额外开销,消除分发的额外开销
无论对于broadcast或者hash分发,数据需要通过进程或者节点之间通信的完成传输,分发的数据越多,消耗的db cpu越多。
并行执行时,数据需要分发,本质上是因为Oracle采用share---everything的集中存储架构,任何数据对每个实例的PX进程都
是共享的。为了对hash join操作分而治之,切分为N个独立的工作单元(假设 DoP=N),必须提前对数据重新分发,数据的分发
操作就是并行带来的额外开销。
使用full或者partial partition wise join技术,可以完全消除分发的额外开销,或者把这种开销降到最低。如果hash join有一边在
连接键上做hash分区,那么优化器可以选择对分区表不分发,因为hash分区已经对数据完成切分,这只需要hash分发hash
join的其中一边,这是partial partition wise join。如果hash join的两边都在连接键上做了hash join分区,那么每个PX进程可以
独立的处理对等的hash分区, 没有数据需要分发,这是full partition wise join。hash分区时,hash join的工作单元就是对等
hash分区包含的数据量,应该控制每个分区的大小,hash join时就可能消除临时表空间的使用,大幅减少所需的PGA。
Partition Wise Join,不需要数据分发。
如果在lineorder的列lo_orderkey上做hash分区,分区数为32个。每个分区的大小接近1G。
使用lo_orderkey 连接时,lineorder不需要再分发。我们继续使用自连接的sql,演示full partition wise join。
此时sql执行时间为1.6分钟,dbtime 6分钟;不分区使用hash分发时,执行时间为2.4分钟,db time 10.5 分钟。使用Partition
Wise join快了三分之一。执行计划中只有一组蓝色的PX进程,不需要对数据进行分发。因为lineorder_hash32的3亿行数据被
切分为32个分区。虽然并行度为4,每个PX进程hash join时,工作单元为一对匹配的hash分区,两边的数据量都为3亿的
1/32。更小的工作单元,使整个hash join消耗的临时表空间下降为 448MB。每个PX进程消耗8对hash分区,可以预见,当我
们把并行度提高到8/16/32,每个PX进程处理的hash分区对数,应该分别为4/2/1,sql执行时间会线性的下降。
蓝色的PX进程为、的p000/p001进程。每个PX进程消耗的db time是平均的,每个PX进程均处理了8对分区的扫描和hash
join。