| -- Tests for Dynamic Partition Elimination, or partition pruning in |
| -- PostgreSQL terms, based on join quals. |
| -- This test requires autovacuum to be disabled to guarantee a consistent state |
| -- after vacuum. An inopportune autovacuum could cause an explicit vacuum to |
| -- skip. That leads to stale relallvisible stats which may prevent picking index |
| -- only scan plan shapes. |
| -- start_matchsubs |
| -- m/Memory Usage: \d+\w?B/ |
| -- s/Memory Usage: \d+\w?B/Memory Usage: ###B/ |
| -- m/Memory: \d+kB/ |
| -- s/Memory: \d+kB/Memory: ###kB/ |
| -- m/Buckets: \d+/ |
| -- s/Buckets: \d+/Buckets: ###/ |
| -- m/Batches: \d+/ |
| -- s/Batches: \d+/Batches: ###/ |
| -- m/Extra Text: \(seg\d+\)/ |
| -- s/Extra Text: \(seg\d+\)/Extra Text: ###/ |
| -- m/Hash chain length \d+\.\d+ avg, \d+ max/ |
| -- s/Hash chain length \d+\.\d+ avg, \d+ max/Hash chain length ###/ |
| -- m/using \d+ of \d+ buckets/ |
| -- s/using \d+ of \d+ buckets/using ## of ### buckets/ |
| -- end_matchsubs |
| drop schema if exists dpe_single cascade; |
| NOTICE: schema "dpe_single" does not exist, skipping |
| create schema dpe_single; |
| set search_path='dpe_single'; |
| set gp_segments_for_planner=2; |
| set optimizer_segments=2; |
| set enable_incremental_sort=on; |
| drop table if exists pt; |
| NOTICE: table "pt" does not exist, skipping |
| drop table if exists pt1; |
| NOTICE: table "pt1" does not exist, skipping |
| drop table if exists t; |
| NOTICE: table "t" does not exist, skipping |
| drop table if exists t1; |
| NOTICE: table "t1" does not exist, skipping |
| create table pt(dist int, pt1 text, pt2 text, pt3 text, ptid int) |
| DISTRIBUTED BY (dist) |
| PARTITION BY RANGE(ptid) |
| ( |
| START (0) END (5) EVERY (1), |
| DEFAULT PARTITION junk_data |
| ) |
| ; |
| -- pt1 table is originally created distributed randomly |
| -- But a random policy impacts data distribution which |
| -- might lead to unstable stats info. Some test cases |
| -- test plan thus become flaky. We avoid flakiness by |
| -- creating the table distributed hashly and after |
| -- loading all the data, changing policy to randomly without |
| -- data movement. Thus every time we will have a static |
| -- data distribution plus randomly policy. |
| create table pt1(dist int, pt1 text, pt2 text, pt3 text, ptid int) |
| DISTRIBUTED BY (dist) |
| PARTITION BY RANGE(ptid) |
| ( |
| START (0) END (5) EVERY (1), |
| DEFAULT PARTITION junk_data |
| ) |
| ; |
| create table t(dist int, tid int, t1 text, t2 text); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'dist' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| create index pt1_idx on pt using btree (pt1); |
| create index ptid_idx on pt using btree (ptid); |
| create index ptid_pt1_idx on pt using btree (ptid, pt1); |
| insert into pt select i, 'hello' || i, 'world', 'drop this', i % 6 from generate_series(0,53) i; |
| insert into t select i, i % 6, 'hello' || i, 'bar' from generate_series(0,1) i; |
| create table t1(dist int, tid int, t1 text, t2 text); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'dist' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| insert into t1 select i, i % 6, 'hello' || i, 'bar' from generate_series(1,2) i; |
| insert into pt1 select * from pt; |
| insert into pt1 select dist, pt1, pt2, pt3, ptid-100 from pt; |
| alter table pt1 set with(REORGANIZE=false) DISTRIBUTED RANDOMLY; |
| vacuum analyze pt; |
| analyze pt1; |
| analyze t; |
| analyze t1; |
| -- |
| -- Simple positive cases |
| -- |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where tid = ptid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = t.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (10 rows) |
| |
| select * from t, pt where tid = ptid; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+---------+-------+-----------+------ |
| 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 |
| (18 rows) |
| |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where tid + 1 = ptid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = (t.tid + 1)) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (10 rows) |
| |
| select * from t, pt where tid + 1 = ptid; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+---------+-------+-----------+------ |
| 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 7 | hello7 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 13 | hello13 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 19 | hello19 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 25 | hello25 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 37 | hello37 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 43 | hello43 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 2 | hello2 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 8 | hello8 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 14 | hello14 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 20 | hello20 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 26 | hello26 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 38 | hello38 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 44 | hello44 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 50 | hello50 | world | drop this | 2 |
| (18 rows) |
| |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where tid = ptid and t1 = 'hello' || tid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| Filter: (t1 = ('hello'::text || (tid)::text)) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = t.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (11 rows) |
| |
| select * from t, pt where tid = ptid and t1 = 'hello' || tid; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+---------+-------+-----------+------ |
| 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 |
| (18 rows) |
| |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where t1 = pt1 and ptid = tid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) |
| -> Nested Loop (actual rows=2 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_pt1_idx on pt (actual rows=1 loops=2) |
| Index Cond: ((ptid = t.tid) AND (pt1 = t.t1)) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (10 rows) |
| |
| select * from t, pt where t1 = pt1 and ptid = tid; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+--------+-------+-----------+------ |
| 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 |
| 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| (2 rows) |
| |
| -- |
| -- in and exists clauses |
| -- |
| explain (costs off, timing off, summary off, analyze) select * from pt where ptid in (select tid from t where t1 = 'hello' || tid); |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) |
| -> Hash Semi Join (actual rows=8 loops=1) |
| Hash Cond: (pt.ptid = t.tid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 2 of 524288 buckets. |
| -> Dynamic Seq Scan on pt (actual rows=8 loops=1) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 2.0 x 3 workers. Max 2 parts (seg0). |
| -> Hash (actual rows=2 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=2 loops=1) |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| Filter: (t1 = ('hello'::text || (tid)::text)) |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (14 rows) |
| |
| select * from pt where ptid in (select tid from t where t1 = 'hello' || tid); |
| dist | pt1 | pt2 | pt3 | ptid |
| ------+---------+-------+-----------+------ |
| 1 | hello1 | world | drop this | 1 |
| 7 | hello7 | world | drop this | 1 |
| 13 | hello13 | world | drop this | 1 |
| 19 | hello19 | world | drop this | 1 |
| 25 | hello25 | world | drop this | 1 |
| 31 | hello31 | world | drop this | 1 |
| 37 | hello37 | world | drop this | 1 |
| 43 | hello43 | world | drop this | 1 |
| 49 | hello49 | world | drop this | 1 |
| 0 | hello0 | world | drop this | 0 |
| 6 | hello6 | world | drop this | 0 |
| 12 | hello12 | world | drop this | 0 |
| 18 | hello18 | world | drop this | 0 |
| 24 | hello24 | world | drop this | 0 |
| 30 | hello30 | world | drop this | 0 |
| 36 | hello36 | world | drop this | 0 |
| 42 | hello42 | world | drop this | 0 |
| 48 | hello48 | world | drop this | 0 |
| (18 rows) |
| |
| explain (costs off, timing off, summary off, analyze) select ptid from pt where ptid in (select tid from t where t1 = 'hello' || tid) and pt1 = 'hello1'; |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=1 loops=1) |
| -> Hash Semi Join (actual rows=1 loops=1) |
| Hash Cond: (pt.ptid = t.tid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 2 of 524288 buckets. |
| -> Dynamic Index Only Scan on ptid_pt1_idx on pt (actual rows=1 loops=1) |
| Index Cond: (pt1 = 'hello1'::text) |
| Heap Fetches: 0 |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 2.0 x 3 workers. Max 2 parts (seg0). |
| -> Hash (actual rows=2 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=2 loops=1) |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| Filter: (t1 = ('hello'::text || (tid)::text)) |
| Optimizer: GPORCA |
| (16 rows) |
| |
| select ptid from pt where ptid in (select tid from t where t1 = 'hello' || tid) and pt1 = 'hello1'; |
| ptid |
| ------ |
| 1 |
| (1 row) |
| |
| -- start_ignore |
| -- Known_opt_diff: MPP-21320 |
| -- end_ignore |
| -- Disable 'CXformSelect2DynamicIndexGet' to avoid picking Dynamic Index Scan and use this test |
| -- to showcase dpe alternative |
| select disable_xform('CXformSelect2DynamicIndexGet'); |
| disable_xform |
| ------------------------------------------ |
| CXformSelect2DynamicIndexGet is disabled |
| (1 row) |
| |
| explain (costs off, timing off, summary off, analyze) select * from pt where exists (select 1 from t where tid = ptid and t1 = 'hello' || tid); |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) |
| -> Hash Semi Join (actual rows=8 loops=1) |
| Hash Cond: (pt.ptid = t.tid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 2 of 524288 buckets. |
| -> Dynamic Seq Scan on pt (actual rows=8 loops=1) |
| Number of partitions to scan: 6 (out of 6) |
| Filter: (NOT (ptid IS NULL)) |
| Partitions scanned: Avg 2.0 x 3 workers. Max 2 parts (seg0). |
| -> Hash (actual rows=2 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=2 loops=1) |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| Filter: (t1 = ('hello'::text || (tid)::text)) |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (15 rows) |
| |
| select * from pt where exists (select 1 from t where tid = ptid and t1 = 'hello' || tid); |
| dist | pt1 | pt2 | pt3 | ptid |
| ------+---------+-------+-----------+------ |
| 49 | hello49 | world | drop this | 1 |
| 43 | hello43 | world | drop this | 1 |
| 37 | hello37 | world | drop this | 1 |
| 31 | hello31 | world | drop this | 1 |
| 25 | hello25 | world | drop this | 1 |
| 19 | hello19 | world | drop this | 1 |
| 13 | hello13 | world | drop this | 1 |
| 7 | hello7 | world | drop this | 1 |
| 1 | hello1 | world | drop this | 1 |
| 48 | hello48 | world | drop this | 0 |
| 42 | hello42 | world | drop this | 0 |
| 36 | hello36 | world | drop this | 0 |
| 30 | hello30 | world | drop this | 0 |
| 24 | hello24 | world | drop this | 0 |
| 18 | hello18 | world | drop this | 0 |
| 12 | hello12 | world | drop this | 0 |
| 6 | hello6 | world | drop this | 0 |
| 0 | hello0 | world | drop this | 0 |
| (18 rows) |
| |
| -- enable xform |
| select enable_xform('CXformSelect2DynamicIndexGet'); |
| enable_xform |
| ----------------------------------------- |
| CXformSelect2DynamicIndexGet is enabled |
| (1 row) |
| |
| -- |
| -- group-by on top |
| -- |
| explain (costs off, timing off, summary off, analyze) select count(*) from t, pt where tid = ptid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------------------- |
| Finalize Aggregate (actual rows=1 loops=1) |
| -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) |
| -> Partial Aggregate (actual rows=1 loops=1) |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Only Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = t.tid) |
| Heap Fetches: 0 |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: GPORCA |
| (13 rows) |
| |
| select count(*) from t, pt where tid = ptid; |
| count |
| ------- |
| 18 |
| (1 row) |
| |
| -- |
| -- window function on top |
| -- |
| explain (costs off, timing off, summary off, analyze) select *, rank() over (order by ptid,pt1) from t, pt where tid = ptid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------------------- |
| WindowAgg (actual rows=18 loops=1) |
| Order By: pt.ptid, pt.pt1 |
| -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) |
| Merge Key: pt.ptid, pt.pt1 |
| -> Sort (actual rows=8 loops=1) |
| Sort Key: pt.ptid, pt.pt1 |
| Sort Method: quicksort Memory: 76kB |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = t.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (16 rows) |
| |
| select *, rank() over (order by ptid,pt1) from t, pt where tid = ptid; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid | rank |
| ------+-----+--------+-----+------+---------+-------+-----------+------+------ |
| 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 | 1 |
| 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 | 2 |
| 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 | 3 |
| 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 | 4 |
| 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 | 5 |
| 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 | 6 |
| 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 | 7 |
| 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 | 8 |
| 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 | 9 |
| 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 | 10 |
| 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 | 11 |
| 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 | 12 |
| 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 | 13 |
| 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 | 14 |
| 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 | 15 |
| 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 | 16 |
| 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 | 17 |
| 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 | 18 |
| (18 rows) |
| |
| -- |
| -- set ops |
| -- |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where tid = ptid |
| union all |
| select * from t, pt where tid + 2 = ptid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=36 loops=1) |
| -> Append (actual rows=14 loops=1) |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = t.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| -> Nested Loop (actual rows=7 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t t_1 (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt pt_1 (actual rows=4 loops=2) |
| Index Cond: (ptid = (t_1.tid + 2)) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (19 rows) |
| |
| select * from t, pt where tid = ptid |
| union all |
| select * from t, pt where tid + 2 = ptid; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+---------+-------+-----------+------ |
| 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 3 | hello3 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 27 | hello27 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 39 | hello39 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 45 | hello45 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 51 | hello51 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 2 | hello2 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 8 | hello8 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 20 | hello20 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 26 | hello26 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 38 | hello38 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 44 | hello44 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 50 | hello50 | world | drop this | 2 |
| (36 rows) |
| |
| -- |
| -- set-ops |
| -- |
| explain (costs off, timing off, summary off, analyze) select count(*) from |
| ( select * from t, pt where tid = ptid |
| union all |
| select * from t, pt where tid + 2 = ptid |
| ) foo; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------------------------- |
| Finalize Aggregate (actual rows=1 loops=1) |
| -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) |
| -> Partial Aggregate (actual rows=1 loops=1) |
| -> Append (actual rows=14 loops=1) |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = t.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| -> Nested Loop (actual rows=7 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t t_1 (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt pt_1 (actual rows=4 loops=2) |
| Index Cond: (ptid = (t_1.tid + 2)) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (21 rows) |
| |
| select count(*) from |
| ( select * from t, pt where tid = ptid |
| union all |
| select * from t, pt where tid + 2 = ptid |
| ) foo; |
| count |
| ------- |
| 36 |
| (1 row) |
| |
| -- |
| -- other join types (NL) |
| -- |
| set enable_hashjoin=off; |
| set enable_nestloop=on; |
| set enable_mergejoin=off; |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where tid = ptid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = t.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (10 rows) |
| |
| select * from t, pt where tid = ptid; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+---------+-------+-----------+------ |
| 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 |
| (18 rows) |
| |
| -- |
| -- index scan |
| -- |
| set enable_nestloop=on; |
| set enable_seqscan=off; |
| set enable_indexscan=on; |
| set enable_bitmapscan=off; |
| set enable_hashjoin=off; |
| -- start_ignore |
| -- Known_opt_diff: MPP-21322 |
| -- end_ignore |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where tid = ptid and pt1 = 'hello0'; |
| QUERY PLAN |
| ------------------------------------------------------------------------------------ |
| Hash Join (actual rows=1 loops=1) |
| Hash Cond: (t.tid = pt.ptid) |
| Extra Text: Hash chain length 1.0 avg, 1 max, using 1 of 262144 buckets. |
| -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Hash (actual rows=1 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Gather Motion 3:1 (slice2; segments: 3) (actual rows=1 loops=1) |
| -> Dynamic Index Scan on pt1_idx on pt (actual rows=1 loops=1) |
| Index Cond: (pt1 = 'hello0'::text) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (13 rows) |
| |
| select * from t, pt where tid = ptid and pt1 = 'hello0'; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+--------+-------+-----------+------ |
| 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 |
| (1 row) |
| |
| -- |
| -- NL Index Scan |
| -- |
| set enable_nestloop=on; |
| set enable_indexscan=on; |
| set enable_seqscan=off; |
| set enable_hashjoin=off; |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where tid = ptid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = t.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (10 rows) |
| |
| select * from t, pt where tid = ptid; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+---------+-------+-----------+------ |
| 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 6 | hello6 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 12 | hello12 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 18 | hello18 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 24 | hello24 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 30 | hello30 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 36 | hello36 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 42 | hello42 | world | drop this | 0 |
| 0 | 0 | hello0 | bar | 48 | hello48 | world | drop this | 0 |
| (18 rows) |
| |
| -- |
| -- Negative test cases where transform does not apply |
| -- |
| set enable_indexscan=off; |
| set enable_seqscan=on; |
| set enable_hashjoin=on; |
| set enable_nestloop=off; |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where t1 = pt1; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) |
| -> Nested Loop (actual rows=2 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on pt1_idx on pt (actual rows=1 loops=2) |
| Index Cond: (pt1 = t.t1) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (10 rows) |
| |
| select * from t, pt where t1 = pt1; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+--------+-------+-----------+------ |
| 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 0 | hello0 | world | drop this | 0 |
| (2 rows) |
| |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where tid < ptid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=81 loops=1) |
| -> Nested Loop (actual rows=31 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=16 loops=2) |
| Index Cond: (ptid > t.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (10 rows) |
| |
| select * from t, pt where tid < ptid; |
| dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+---------+-------+-----------+------ |
| 1 | 1 | hello1 | bar | 2 | hello2 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | hello2 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 8 | hello8 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 8 | hello8 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 14 | hello14 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 14 | hello14 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 20 | hello20 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 20 | hello20 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 26 | hello26 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 26 | hello26 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 32 | hello32 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 32 | hello32 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 38 | hello38 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 38 | hello38 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 44 | hello44 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 44 | hello44 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 50 | hello50 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 50 | hello50 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 4 | hello4 | world | drop this | 4 |
| 0 | 0 | hello0 | bar | 4 | hello4 | world | drop this | 4 |
| 1 | 1 | hello1 | bar | 10 | hello10 | world | drop this | 4 |
| 0 | 0 | hello0 | bar | 10 | hello10 | world | drop this | 4 |
| 1 | 1 | hello1 | bar | 16 | hello16 | world | drop this | 4 |
| 0 | 0 | hello0 | bar | 16 | hello16 | world | drop this | 4 |
| 1 | 1 | hello1 | bar | 22 | hello22 | world | drop this | 4 |
| 0 | 0 | hello0 | bar | 22 | hello22 | world | drop this | 4 |
| 1 | 1 | hello1 | bar | 28 | hello28 | world | drop this | 4 |
| 0 | 0 | hello0 | bar | 28 | hello28 | world | drop this | 4 |
| 1 | 1 | hello1 | bar | 34 | hello34 | world | drop this | 4 |
| 0 | 0 | hello0 | bar | 34 | hello34 | world | drop this | 4 |
| 1 | 1 | hello1 | bar | 40 | hello40 | world | drop this | 4 |
| 0 | 0 | hello0 | bar | 40 | hello40 | world | drop this | 4 |
| 1 | 1 | hello1 | bar | 46 | hello46 | world | drop this | 4 |
| 0 | 0 | hello0 | bar | 46 | hello46 | world | drop this | 4 |
| 1 | 1 | hello1 | bar | 52 | hello52 | world | drop this | 4 |
| 0 | 0 | hello0 | bar | 52 | hello52 | world | drop this | 4 |
| 1 | 1 | hello1 | bar | 5 | hello5 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 5 | hello5 | world | drop this | 5 |
| 1 | 1 | hello1 | bar | 11 | hello11 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 11 | hello11 | world | drop this | 5 |
| 1 | 1 | hello1 | bar | 17 | hello17 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 17 | hello17 | world | drop this | 5 |
| 1 | 1 | hello1 | bar | 23 | hello23 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 23 | hello23 | world | drop this | 5 |
| 1 | 1 | hello1 | bar | 29 | hello29 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 29 | hello29 | world | drop this | 5 |
| 1 | 1 | hello1 | bar | 35 | hello35 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 35 | hello35 | world | drop this | 5 |
| 1 | 1 | hello1 | bar | 41 | hello41 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 41 | hello41 | world | drop this | 5 |
| 1 | 1 | hello1 | bar | 47 | hello47 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 47 | hello47 | world | drop this | 5 |
| 1 | 1 | hello1 | bar | 53 | hello53 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 53 | hello53 | world | drop this | 5 |
| 0 | 0 | hello0 | bar | 1 | hello1 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 7 | hello7 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 13 | hello13 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 19 | hello19 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 25 | hello25 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 31 | hello31 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 37 | hello37 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 43 | hello43 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 49 | hello49 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 3 | hello3 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 3 | hello3 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 9 | hello9 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 9 | hello9 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 15 | hello15 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 15 | hello15 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 21 | hello21 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 21 | hello21 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 27 | hello27 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 27 | hello27 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 33 | hello33 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 33 | hello33 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 39 | hello39 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 39 | hello39 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 45 | hello45 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 45 | hello45 | world | drop this | 3 |
| 1 | 1 | hello1 | bar | 51 | hello51 | world | drop this | 3 |
| 0 | 0 | hello0 | bar | 51 | hello51 | world | drop this | 3 |
| (81 rows) |
| |
| reset enable_indexscan; |
| reset enable_seqscan; |
| reset enable_hashjoin; |
| reset enable_nestloop; |
| -- |
| -- multiple joins |
| -- |
| -- one of the joined tables can be used for partition elimination, the other can not |
| explain (costs off, timing off, summary off, analyze) select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------------- |
| Hash Join (actual rows=36 loops=1) |
| Hash Cond: (t1.t2 = t.t2) |
| Extra Text: Hash chain length 2.0 avg, 2 max, using 1 of 262144 buckets. |
| -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=18 loops=1) |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t1 (actual rows=1 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=4 loops=2) |
| Index Cond: (ptid = t1.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 2 scans. Max 6 parts (seg0). |
| -> Hash (actual rows=2 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Gather Motion 3:1 (slice3; segments: 3) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (17 rows) |
| |
| select * from t, t1, pt where t1.t2 = t.t2 and t1.tid = ptid; |
| dist | tid | t1 | t2 | dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+-----+--------+-----+------+---------+-------+-----------+------ |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 2 | hello2 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 2 | hello2 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 8 | hello8 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 8 | hello8 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 20 | hello20 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 20 | hello20 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 26 | hello26 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 26 | hello26 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 38 | hello38 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 38 | hello38 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 44 | hello44 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 44 | hello44 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 50 | hello50 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 50 | hello50 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 |
| 0 | 0 | hello0 | bar | 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 14 | hello14 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 14 | hello14 | world | drop this | 2 |
| 1 | 1 | hello1 | bar | 2 | 2 | hello2 | bar | 32 | hello32 | world | drop this | 2 |
| 0 | 0 | hello0 | bar | 2 | 2 | hello2 | bar | 32 | hello32 | world | drop this | 2 |
| (36 rows) |
| |
| -- Both joined tables can be used for partition elimination. Only partitions |
| -- that contain matching rows for both joins need to be scanned. |
| -- have to do some tricks to coerce the planner to choose the plan we want. |
| begin; |
| insert into t select i, -100, 'dummy' from generate_series(1,10) i; |
| insert into t1 select i, -100, 'dummy' from generate_series(1,10) i; |
| analyze t; |
| analyze t1; |
| explain (costs off, timing off, summary off, analyze) select * from t, t1, pt where t1.tid = ptid and t.tid = ptid; |
| QUERY PLAN |
| ------------------------------------------------------------------------------------------------------------ |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=9 loops=1) |
| -> Hash Join (actual rows=9 loops=1) |
| Hash Cond: (t.tid = pt.ptid) |
| Extra Text: (seg1) Hash chain length 9.0 avg, 9 max, using 1 of 262144 buckets. |
| -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=2 loops=1) |
| Hash Key: t.tid |
| -> Seq Scan on t (actual rows=5 loops=1) |
| -> Hash (actual rows=9 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Redistribute Motion 3:3 (slice3; segments: 3) (actual rows=9 loops=1) |
| Hash Key: pt.ptid |
| -> Nested Loop (actual rows=8 loops=1) |
| Join Filter: true |
| -> Broadcast Motion 3:3 (slice4; segments: 3) (actual rows=12 loops=1) |
| -> Seq Scan on t1 (actual rows=6 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt (actual rows=1 loops=12) |
| Index Cond: (ptid = t1.tid) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers of 12 scans. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (20 rows) |
| |
| select * from t, t1, pt where t1.tid = ptid and t.tid = ptid; |
| dist | tid | t1 | t2 | dist | tid | t1 | t2 | dist | pt1 | pt2 | pt3 | ptid |
| ------+-----+--------+-----+------+-----+--------+-----+------+---------+-------+-----------+------ |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 13 | hello13 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 25 | hello25 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 43 | hello43 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 7 | hello7 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 19 | hello19 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 37 | hello37 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 1 | hello1 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 31 | hello31 | world | drop this | 1 |
| 1 | 1 | hello1 | bar | 1 | 1 | hello1 | bar | 49 | hello49 | world | drop this | 1 |
| (9 rows) |
| |
| rollback; |
| -- One non-joined table contributing to partition elimination in two different |
| -- partitioned tables |
| begin; |
| -- have to force the planner for it to consider the kind of plan we want |
| -- to test |
| set local from_collapse_limit = 1; |
| set local join_collapse_limit = 1; |
| explain (costs off, timing off, summary off, analyze) select * from t1 inner join (select pt1.*, pt2.ptid as ptid2 from pt as pt1, pt as pt2 WHERE pt1.ptid <= pt2.ptid and pt1.dist = pt2.dist ) as ptx ON t1.dist = ptx.dist and t1.tid = ptx.ptid and t1.tid = ptx.ptid2; |
| QUERY PLAN |
| ------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) |
| -> Nested Loop (actual rows=1 loops=1) |
| Join Filter: true |
| -> Nested Loop (actual rows=1 loops=1) |
| Join Filter: true |
| -> Seq Scan on t1 (actual rows=1 loops=1) |
| -> Dynamic Index Scan on ptid_idx on pt pt2 (actual rows=1 loops=1) |
| Index Cond: (ptid = t1.tid) |
| Filter: ((ptid = t1.tid) AND (t1.dist = dist)) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 2 workers. Max 6 parts (seg0). |
| -> Dynamic Index Scan on ptid_idx on pt pt1 (actual rows=1 loops=1) |
| Index Cond: ((ptid <= pt2.ptid) AND (ptid = pt2.ptid)) |
| Filter: ((ptid <= pt2.ptid) AND (ptid = pt2.ptid) AND (dist = pt2.dist)) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 2 workers. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (17 rows) |
| |
| rollback; |
| -- |
| -- Partitioned table on both sides of the join. This will create a result node as Append node is |
| -- not projection capable. |
| -- |
| explain (costs off, timing off, summary off, analyze) select * from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0' order by pt1.dist; |
| QUERY PLAN |
| ------------------------------------------------------------------------------------------------------ |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=9 loops=1) |
| Merge Key: pt1.dist |
| -> Sort (actual rows=5 loops=1) |
| Sort Key: pt1.dist |
| Sort Method: quicksort Memory: 75kB |
| -> Hash Join (actual rows=5 loops=1) |
| Hash Cond: (pt1.ptid = pt.ptid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 131072 buckets. |
| -> Dynamic Seq Scan on pt1 (actual rows=5 loops=1) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 1.0 x 3 workers. Max 1 parts (seg0). |
| -> Hash (actual rows=1 loops=1) |
| Buckets: 131072 Batches: 1 Memory Usage: 1025kB |
| -> Partition Selector (selector id: $0) (actual rows=1 loops=1) |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) |
| -> Dynamic Index Scan on pt1_idx on pt (actual rows=1 loops=1) |
| Index Cond: (pt1 = 'hello0'::text) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (20 rows) |
| |
| select * from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0' order by pt1.dist; |
| dist | pt1 | pt2 | pt3 | ptid | dist | pt1 | pt2 | pt3 | ptid |
| ------+--------+-------+-----------+------+------+---------+-------+-----------+------ |
| 0 | hello0 | world | drop this | 0 | 0 | hello0 | world | drop this | 0 |
| 0 | hello0 | world | drop this | 0 | 6 | hello6 | world | drop this | 0 |
| 0 | hello0 | world | drop this | 0 | 12 | hello12 | world | drop this | 0 |
| 0 | hello0 | world | drop this | 0 | 18 | hello18 | world | drop this | 0 |
| 0 | hello0 | world | drop this | 0 | 24 | hello24 | world | drop this | 0 |
| 0 | hello0 | world | drop this | 0 | 30 | hello30 | world | drop this | 0 |
| 0 | hello0 | world | drop this | 0 | 36 | hello36 | world | drop this | 0 |
| 0 | hello0 | world | drop this | 0 | 42 | hello42 | world | drop this | 0 |
| 0 | hello0 | world | drop this | 0 | 48 | hello48 | world | drop this | 0 |
| (9 rows) |
| |
| explain (costs off, timing off, summary off, analyze) select count(*) from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0'; |
| QUERY PLAN |
| ------------------------------------------------------------------------------------------------------------ |
| Finalize Aggregate (actual rows=1 loops=1) |
| -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) |
| -> Partial Aggregate (actual rows=1 loops=1) |
| -> Hash Join (actual rows=5 loops=1) |
| Hash Cond: (pt1.ptid = pt.ptid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. |
| -> Dynamic Seq Scan on pt1 (actual rows=5 loops=1) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 1.0 x 3 workers. Max 1 parts (seg0). |
| -> Hash (actual rows=1 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=1 loops=1) |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) |
| -> Dynamic Index Only Scan on ptid_pt1_idx on pt (actual rows=1 loops=1) |
| Index Cond: (pt1 = 'hello0'::text) |
| Heap Fetches: 0 |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 6.0 x 3 workers. Max 6 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (18 rows) |
| |
| select count(*) from pt, pt1 where pt.ptid = pt1.ptid and pt.pt1 = 'hello0'; |
| count |
| ------- |
| 9 |
| (1 row) |
| |
| -- |
| -- Partition Selector under Material in NestLoopJoin inner side |
| -- |
| drop table if exists pt; |
| drop table if exists t; |
| create table t(id int, a int); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| create table pt(id int, b int) DISTRIBUTED BY (id) PARTITION BY RANGE(b) (START (0) END (5) EVERY (1)); |
| insert into t select i, i from generate_series(0,4) i; |
| insert into pt select i, i from generate_series(0,4) i; |
| analyze t; |
| analyze pt; |
| begin; |
| set enable_hashjoin=off; |
| set enable_seqscan=on; |
| set enable_nestloop=on; |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where a = b; |
| QUERY PLAN |
| ------------------------------------------------------------------------------------------ |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=5 loops=1) |
| -> Hash Join (actual rows=3 loops=1) |
| Hash Cond: (t.a = pt.b) |
| Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 3 of 524288 buckets. |
| -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) |
| Hash Key: t.a |
| -> Seq Scan on t (actual rows=3 loops=1) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Redistribute Motion 3:3 (slice3; segments: 3) (actual rows=3 loops=1) |
| Hash Key: pt.b |
| -> Dynamic Seq Scan on pt (actual rows=3 loops=1) |
| Number of partitions to scan: 5 (out of 5) |
| Partitions scanned: Avg 5.0 x 3 workers. Max 5 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (14 rows) |
| |
| select * from t, pt where a = b; |
| id | a | id | b |
| ----+---+----+--- |
| 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 |
| 3 | 3 | 3 | 3 |
| 4 | 4 | 4 | 4 |
| (5 rows) |
| |
| rollback; |
| -- |
| -- partition selector with 0 tuples and 0 matched partitions |
| -- |
| drop table if exists t; |
| drop table if exists pt; |
| create table t(a int); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| create table pt(b int) DISTRIBUTED BY (b) PARTITION BY RANGE(b) |
| (START (0) END (5) EVERY (1)); |
| begin; |
| set enable_hashjoin=off; -- foring nestloop join |
| set enable_nestloop=on; |
| set enable_seqscan=on; |
| -- 7 in seg1, 8 in seg2, no data in seg0 |
| insert into t select i from generate_series(7,8) i; |
| -- 0~2 in seg0, 3~4 in seg 1, no data in seg2 |
| insert into pt select i from generate_series(0,4) i; |
| -- Insert some more rows to coerce the planner to put 'pt' on the outer |
| -- side of the join. |
| insert into t select i from generate_series(7,8) i; |
| insert into pt select 0 from generate_series(1,1000) g; |
| analyze t; |
| analyze pt; |
| explain (costs off, timing off, summary off, analyze) select * from t, pt where a = b; |
| QUERY PLAN |
| -------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=0 loops=1) |
| -> Hash Join (actual rows=0 loops=1) |
| Hash Cond: (pt.b = t.a) |
| -> Dynamic Seq Scan on pt (actual rows=0 loops=1) |
| Number of partitions to scan: 5 (out of 5) |
| -> Hash (actual rows=4 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=4 loops=1) |
| -> Seq Scan on t (actual rows=4 loops=1) |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (10 rows) |
| |
| select * from t, pt where a = b; |
| a | b |
| ---+--- |
| (0 rows) |
| |
| rollback; |
| -- |
| -- Multi-level partitions |
| -- |
| drop schema if exists dpe_multi cascade; |
| NOTICE: schema "dpe_multi" does not exist, skipping |
| create schema dpe_multi; |
| set search_path='dpe_multi'; |
| set gp_segments_for_planner=2; |
| set optimizer_segments=2; |
| create table dim1(dist int, pid int, code text, t1 text); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'dist' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| insert into dim1 values (1, 0, 'OH', 'world1'); |
| insert into dim1 values (1, 1, 'OH', 'world2'); |
| insert into dim1 values (1, 100, 'GA', 'world2'); -- should not have a match at all |
| analyze dim1; |
| create table fact1(dist int, pid int, code text, u int) |
| partition by range(pid) |
| subpartition by list(code) |
| subpartition template |
| ( |
| subpartition ca values('CA'), |
| subpartition oh values('OH'), |
| subpartition wa values('WA') |
| ) |
| ( |
| start (0) |
| end (4) |
| every (1) |
| ); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'dist' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| insert into fact1 select 1, i % 4 , 'OH', i from generate_series (1,100) i; |
| insert into fact1 select 1, i % 4 , 'CA', i + 10000 from generate_series (1,100) i; |
| -- |
| -- Join on all partitioning columns |
| -- |
| set gp_dynamic_partition_pruning=off; |
| explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid and dim1.code=fact1.code) order by fact1.u; |
| QUERY PLAN |
| ---------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=50 loops=1) |
| Merge Key: fact1.u |
| -> Sort (actual rows=50 loops=1) |
| Sort Key: fact1.u |
| Sort Method: quicksort Memory: 158kB |
| -> Hash Join (actual rows=50 loops=1) |
| Hash Cond: ((fact1.pid = dim1.pid) AND (fact1.code = dim1.code)) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. |
| -> Append (actual rows=200 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_wa fact1_3 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_ca fact1_4 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_5 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_wa fact1_6 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_ca fact1_7 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_8 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_wa fact1_9 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_ca fact1_10 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (actual rows=0 loops=1) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 131072 Batches: 1 Memory Usage: 1025kB |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (26 rows) |
| |
| select * from dim1 inner join fact1 on (dim1.pid=fact1.pid and dim1.code=fact1.code) order by fact1.u; |
| dist | pid | code | t1 | dist | pid | code | u |
| ------+-----+------+--------+------+-----+------+----- |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 1 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 4 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 5 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 8 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 9 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 12 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 13 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 16 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 17 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 20 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 21 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 24 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 25 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 28 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 29 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 32 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 33 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 36 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 37 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 40 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 41 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 44 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 45 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 48 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 49 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 52 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 53 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 56 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 57 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 60 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 61 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 64 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 65 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 68 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 69 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 72 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 73 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 76 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 77 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 80 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 81 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 84 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 85 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 88 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 89 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 92 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 93 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 96 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 97 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 100 |
| (50 rows) |
| |
| set gp_dynamic_partition_pruning=on; |
| explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid and dim1.code=fact1.code) order by fact1.u; |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=50 loops=1) |
| Merge Key: fact1.u |
| -> Sort (actual rows=50 loops=1) |
| Sort Key: fact1.u |
| Sort Method: quicksort Memory: 158kB |
| -> Hash Join (actual rows=50 loops=1) |
| Hash Cond: ((fact1.pid = dim1.pid) AND (fact1.code = dim1.code)) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. |
| -> Append (actual rows=50 loops=1) |
| Partition Selectors: $0 |
| -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (never executed) |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_wa fact1_3 (never executed) |
| -> Seq Scan on fact1_1_prt_2_2_prt_ca fact1_4 (never executed) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_5 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_wa fact1_6 (never executed) |
| -> Seq Scan on fact1_1_prt_3_2_prt_ca fact1_7 (never executed) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_8 (never executed) |
| -> Seq Scan on fact1_1_prt_3_2_prt_wa fact1_9 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_ca fact1_10 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (never executed) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 131072 Batches: 1 Memory Usage: 1025kB |
| -> Partition Selector (selector id: $0) (actual rows=3 loops=1) |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (27 rows) |
| |
| select * from dim1 inner join fact1 on (dim1.pid=fact1.pid and dim1.code=fact1.code) order by fact1.u; |
| dist | pid | code | t1 | dist | pid | code | u |
| ------+-----+------+--------+------+-----+------+----- |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 1 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 4 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 5 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 8 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 9 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 12 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 13 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 16 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 17 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 20 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 21 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 24 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 25 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 28 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 29 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 32 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 33 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 36 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 37 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 40 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 41 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 44 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 45 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 48 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 49 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 52 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 53 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 56 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 57 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 60 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 61 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 64 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 65 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 68 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 69 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 72 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 73 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 76 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 77 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 80 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 81 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 84 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 85 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 88 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 89 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 92 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 93 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 96 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 97 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 100 |
| (50 rows) |
| |
| -- |
| -- Join on one of the partitioning columns |
| -- |
| set gp_dynamic_partition_pruning=off; |
| explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) order by fact1.u; |
| QUERY PLAN |
| ---------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=100 loops=1) |
| Merge Key: fact1.u |
| -> Sort (actual rows=100 loops=1) |
| Sort Key: fact1.u |
| Sort Method: quicksort Memory: 166kB |
| -> Hash Join (actual rows=100 loops=1) |
| Hash Cond: (fact1.pid = dim1.pid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. |
| -> Append (actual rows=200 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_wa fact1_3 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_ca fact1_4 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_5 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_wa fact1_6 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_ca fact1_7 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_8 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_wa fact1_9 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_ca fact1_10 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (actual rows=0 loops=1) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 131072 Batches: 1 Memory Usage: 1025kB |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (26 rows) |
| |
| select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) order by fact1.u; |
| dist | pid | code | t1 | dist | pid | code | u |
| ------+-----+------+--------+------+-----+------+------- |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 1 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 4 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 5 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 8 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 9 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 12 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 13 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 16 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 17 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 20 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 21 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 24 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 25 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 28 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 29 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 32 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 33 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 36 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 37 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 40 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 41 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 44 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 45 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 48 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 49 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 52 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 53 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 56 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 57 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 60 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 61 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 64 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 65 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 68 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 69 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 72 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 73 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 76 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 77 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 80 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 81 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 84 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 85 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 88 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 89 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 92 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 93 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 96 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 97 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 100 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10001 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10004 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10005 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10008 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10009 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10012 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10013 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10016 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10017 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10020 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10021 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10024 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10025 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10028 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10029 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10032 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10033 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10036 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10037 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10040 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10041 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10044 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10045 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10048 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10049 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10052 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10053 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10056 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10057 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10060 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10061 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10064 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10065 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10068 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10069 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10072 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10073 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10076 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10077 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10080 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10081 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10084 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10085 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10088 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10089 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10092 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10093 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10096 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10097 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10100 |
| (100 rows) |
| |
| set gp_dynamic_partition_pruning=on; |
| explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) order by fact1.u; |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=100 loops=1) |
| Merge Key: fact1.u |
| -> Sort (actual rows=100 loops=1) |
| Sort Key: fact1.u |
| Sort Method: quicksort Memory: 166kB |
| -> Hash Join (actual rows=100 loops=1) |
| Hash Cond: (fact1.pid = dim1.pid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. |
| -> Append (actual rows=100 loops=1) |
| Partition Selectors: $0 |
| -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_wa fact1_3 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_ca fact1_4 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_5 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_wa fact1_6 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_ca fact1_7 (never executed) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_8 (never executed) |
| -> Seq Scan on fact1_1_prt_3_2_prt_wa fact1_9 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_ca fact1_10 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (never executed) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 131072 Batches: 1 Memory Usage: 1025kB |
| -> Partition Selector (selector id: $0) (actual rows=3 loops=1) |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (28 rows) |
| |
| select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) order by fact1.u; |
| dist | pid | code | t1 | dist | pid | code | u |
| ------+-----+------+--------+------+-----+------+------- |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 1 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 4 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 5 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 8 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 9 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 12 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 13 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 16 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 17 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 20 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 21 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 24 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 25 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 28 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 29 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 32 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 33 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 36 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 37 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 40 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 41 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 44 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 45 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 48 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 49 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 52 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 53 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 56 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 57 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 60 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 61 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 64 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 65 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 68 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 69 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 72 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 73 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 76 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 77 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 80 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 81 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 84 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 85 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 88 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 89 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 92 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 93 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 96 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 97 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 100 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10001 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10004 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10005 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10008 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10009 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10012 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10013 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10016 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10017 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10020 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10021 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10024 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10025 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10028 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10029 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10032 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10033 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10036 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10037 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10040 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10041 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10044 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10045 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10048 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10049 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10052 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10053 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10056 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10057 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10060 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10061 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10064 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10065 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10068 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10069 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10072 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10073 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10076 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10077 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10080 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10081 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10084 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10085 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10088 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10089 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10092 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10093 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10096 |
| 1 | 1 | OH | world2 | 1 | 1 | CA | 10097 |
| 1 | 0 | OH | world1 | 1 | 0 | CA | 10100 |
| (100 rows) |
| |
| -- |
| -- Join on the subpartitioning column only |
| -- |
| set gp_dynamic_partition_pruning=off; |
| explain (costs off, timing off, summary off, analyze) |
| select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fact1.code); |
| QUERY PLAN |
| ---------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=200 loops=1) |
| -> Hash Join (actual rows=200 loops=1) |
| Hash Cond: ((fact1.dist = dim1.dist) AND (fact1.code = dim1.code)) |
| Extra Text: (seg1) Hash chain length 1.5 avg, 2 max, using 2 of 262144 buckets. |
| -> Append (actual rows=200 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_wa fact1_3 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_ca fact1_4 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_5 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_wa fact1_6 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_ca fact1_7 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_8 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_wa fact1_9 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_ca fact1_10 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (actual rows=0 loops=1) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (21 rows) |
| |
| select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fact1.code); |
| dist | pid | code | t1 | dist | pid | code | u |
| ------+-----+------+--------+------+-----+------+----- |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 4 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 4 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 8 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 8 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 12 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 12 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 16 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 16 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 20 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 20 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 24 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 24 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 28 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 28 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 32 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 32 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 36 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 36 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 40 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 40 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 44 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 44 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 48 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 48 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 52 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 52 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 56 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 56 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 60 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 60 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 64 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 64 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 68 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 68 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 72 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 72 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 76 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 76 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 80 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 80 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 84 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 84 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 88 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 88 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 92 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 92 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 96 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 96 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 100 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 100 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 1 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 1 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 5 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 5 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 9 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 9 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 13 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 13 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 17 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 17 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 21 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 21 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 25 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 25 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 29 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 29 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 33 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 33 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 37 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 37 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 41 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 41 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 45 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 45 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 49 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 49 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 53 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 53 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 57 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 57 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 61 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 61 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 65 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 65 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 69 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 69 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 73 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 73 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 77 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 77 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 81 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 81 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 85 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 85 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 89 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 89 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 93 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 93 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 97 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 97 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 2 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 2 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 6 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 6 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 10 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 10 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 14 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 14 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 18 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 18 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 22 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 22 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 26 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 26 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 30 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 30 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 34 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 34 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 38 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 38 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 42 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 42 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 46 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 46 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 50 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 50 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 54 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 54 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 58 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 58 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 62 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 62 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 66 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 66 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 70 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 70 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 74 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 74 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 78 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 78 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 82 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 82 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 86 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 86 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 90 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 90 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 94 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 94 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 98 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 98 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 3 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 3 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 7 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 7 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 11 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 11 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 15 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 15 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 19 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 19 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 23 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 23 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 27 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 27 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 31 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 31 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 35 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 35 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 39 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 39 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 43 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 43 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 47 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 47 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 51 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 51 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 55 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 55 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 59 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 59 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 63 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 63 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 67 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 67 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 71 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 71 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 75 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 75 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 79 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 79 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 83 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 83 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 87 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 87 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 91 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 91 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 95 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 95 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 99 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 99 |
| (200 rows) |
| |
| set gp_dynamic_partition_pruning=on; |
| explain (costs off, timing off, summary off, analyze) |
| select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fact1.code); |
| QUERY PLAN |
| ---------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=200 loops=1) |
| -> Hash Join (actual rows=200 loops=1) |
| Hash Cond: ((fact1.dist = dim1.dist) AND (fact1.code = dim1.code)) |
| Extra Text: (seg1) Hash chain length 1.5 avg, 2 max, using 2 of 262144 buckets. |
| -> Append (actual rows=100 loops=1) |
| Partition Selectors: $0 |
| -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (never executed) |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_wa fact1_3 (never executed) |
| -> Seq Scan on fact1_1_prt_2_2_prt_ca fact1_4 (never executed) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_5 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_wa fact1_6 (never executed) |
| -> Seq Scan on fact1_1_prt_3_2_prt_ca fact1_7 (never executed) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_8 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_wa fact1_9 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_ca fact1_10 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (never executed) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Partition Selector (selector id: $0) (actual rows=3 loops=1) |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (22 rows) |
| |
| select * from dim1 inner join fact1 on (dim1.dist = fact1.dist and dim1.code=fact1.code); |
| dist | pid | code | t1 | dist | pid | code | u |
| ------+-----+------+--------+------+-----+------+----- |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 4 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 4 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 8 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 8 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 12 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 12 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 16 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 16 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 20 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 20 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 24 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 24 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 28 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 28 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 32 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 32 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 36 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 36 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 40 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 40 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 44 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 44 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 48 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 48 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 52 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 52 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 56 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 56 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 60 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 60 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 64 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 64 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 68 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 68 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 72 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 72 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 76 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 76 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 80 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 80 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 84 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 84 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 88 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 88 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 92 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 92 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 96 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 96 |
| 1 | 1 | OH | world2 | 1 | 0 | OH | 100 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 100 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 1 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 1 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 5 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 5 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 9 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 9 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 13 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 13 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 17 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 17 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 21 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 21 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 25 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 25 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 29 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 29 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 33 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 33 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 37 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 37 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 41 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 41 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 45 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 45 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 49 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 49 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 53 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 53 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 57 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 57 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 61 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 61 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 65 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 65 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 69 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 69 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 73 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 73 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 77 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 77 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 81 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 81 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 85 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 85 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 89 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 89 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 93 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 93 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 97 |
| 1 | 0 | OH | world1 | 1 | 1 | OH | 97 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 2 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 2 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 6 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 6 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 10 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 10 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 14 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 14 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 18 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 18 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 22 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 22 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 26 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 26 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 30 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 30 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 34 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 34 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 38 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 38 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 42 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 42 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 46 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 46 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 50 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 50 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 54 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 54 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 58 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 58 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 62 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 62 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 66 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 66 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 70 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 70 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 74 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 74 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 78 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 78 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 82 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 82 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 86 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 86 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 90 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 90 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 94 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 94 |
| 1 | 1 | OH | world2 | 1 | 2 | OH | 98 |
| 1 | 0 | OH | world1 | 1 | 2 | OH | 98 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 3 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 3 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 7 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 7 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 11 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 11 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 15 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 15 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 19 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 19 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 23 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 23 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 27 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 27 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 31 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 31 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 35 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 35 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 39 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 39 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 43 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 43 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 47 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 47 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 51 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 51 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 55 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 55 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 59 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 59 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 63 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 63 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 67 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 67 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 71 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 71 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 75 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 75 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 79 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 79 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 83 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 83 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 87 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 87 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 91 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 91 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 95 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 95 |
| 1 | 1 | OH | world2 | 1 | 3 | OH | 99 |
| 1 | 0 | OH | world1 | 1 | 3 | OH | 99 |
| (200 rows) |
| |
| -- |
| -- Join on one of the partitioning columns and static elimination on other |
| -- |
| set gp_dynamic_partition_pruning=off; |
| explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=50 loops=1) |
| Merge Key: fact1.u |
| -> Sort (actual rows=50 loops=1) |
| Sort Key: fact1.u |
| Sort Method: quicksort Memory: 158kB |
| -> Hash Join (actual rows=50 loops=1) |
| Hash Cond: (fact1.pid = dim1.pid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. |
| -> Append (actual rows=100 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_1 (actual rows=25 loops=1) |
| Filter: (code = 'OH'::text) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| Filter: (code = 'OH'::text) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_3 (actual rows=25 loops=1) |
| Filter: (code = 'OH'::text) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_4 (actual rows=25 loops=1) |
| Filter: (code = 'OH'::text) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 131072 Batches: 1 Memory Usage: 1025kB |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (21 rows) |
| |
| select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; |
| dist | pid | code | t1 | dist | pid | code | u |
| ------+-----+------+--------+------+-----+------+----- |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 1 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 4 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 5 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 8 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 9 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 12 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 13 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 16 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 17 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 20 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 21 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 24 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 25 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 28 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 29 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 32 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 33 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 36 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 37 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 40 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 41 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 44 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 45 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 48 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 49 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 52 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 53 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 56 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 57 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 60 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 61 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 64 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 65 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 68 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 69 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 72 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 73 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 76 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 77 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 80 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 81 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 84 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 85 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 88 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 89 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 92 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 93 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 96 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 97 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 100 |
| (50 rows) |
| |
| set gp_dynamic_partition_pruning=on; |
| explain (costs off, timing off, summary off, analyze) select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=50 loops=1) |
| Merge Key: fact1.u |
| -> Sort (actual rows=50 loops=1) |
| Sort Key: fact1.u |
| Sort Method: quicksort Memory: 158kB |
| -> Hash Join (actual rows=50 loops=1) |
| Hash Cond: (fact1.pid = dim1.pid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 131072 buckets. |
| -> Append (actual rows=50 loops=1) |
| Partition Selectors: $0 |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_1 (actual rows=25 loops=1) |
| Filter: (code = 'OH'::text) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| Filter: (code = 'OH'::text) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_3 (never executed) |
| Filter: (code = 'OH'::text) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_4 (never executed) |
| Filter: (code = 'OH'::text) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 131072 Batches: 1 Memory Usage: 1025kB |
| -> Partition Selector (selector id: $0) (actual rows=3 loops=1) |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=3 loops=1) |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (23 rows) |
| |
| select * from dim1 inner join fact1 on (dim1.pid=fact1.pid) and fact1.code = 'OH' order by fact1.u; |
| dist | pid | code | t1 | dist | pid | code | u |
| ------+-----+------+--------+------+-----+------+----- |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 1 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 4 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 5 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 8 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 9 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 12 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 13 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 16 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 17 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 20 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 21 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 24 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 25 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 28 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 29 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 32 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 33 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 36 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 37 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 40 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 41 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 44 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 45 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 48 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 49 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 52 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 53 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 56 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 57 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 60 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 61 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 64 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 65 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 68 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 69 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 72 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 73 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 76 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 77 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 80 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 81 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 84 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 85 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 88 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 89 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 92 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 93 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 96 |
| 1 | 1 | OH | world2 | 1 | 1 | OH | 97 |
| 1 | 0 | OH | world1 | 1 | 0 | OH | 100 |
| (50 rows) |
| |
| -- |
| -- add aggregates |
| -- |
| set gp_dynamic_partition_pruning=off; |
| explain (costs off, timing off, summary off, analyze) select fact1.code, count(*) from dim1 inner join fact1 on (dim1.pid=fact1.pid) group by 1 order by 1; |
| QUERY PLAN |
| ---------------------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) |
| Merge Key: fact1.code |
| -> GroupAggregate (actual rows=2 loops=1) |
| Group Key: fact1.code |
| -> Sort (actual rows=100 loops=1) |
| Sort Key: fact1.code |
| Sort Method: quicksort Memory: 160kB |
| -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=100 loops=1) |
| Hash Key: fact1.code |
| -> Hash Join (actual rows=100 loops=1) |
| Hash Cond: (fact1.pid = dim1.pid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 262144 buckets. |
| -> Append (actual rows=200 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_wa fact1_3 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_ca fact1_4 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_5 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_wa fact1_6 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_ca fact1_7 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_8 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_wa fact1_9 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_ca fact1_10 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (actual rows=0 loops=1) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=3 loops=1) |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (29 rows) |
| |
| select fact1.code, count(*) from dim1 inner join fact1 on (dim1.pid=fact1.pid) group by 1 order by 1; |
| code | count |
| ------+------- |
| CA | 50 |
| OH | 50 |
| (2 rows) |
| |
| set gp_dynamic_partition_pruning=on; |
| explain (costs off, timing off, summary off, analyze) select fact1.code, count(*) from dim1 inner join fact1 on (dim1.pid=fact1.pid) group by 1 order by 1; |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) |
| Merge Key: fact1.code |
| -> GroupAggregate (actual rows=2 loops=1) |
| Group Key: fact1.code |
| -> Sort (actual rows=100 loops=1) |
| Sort Key: fact1.code |
| Sort Method: quicksort Memory: 160kB |
| -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=100 loops=1) |
| Hash Key: fact1.code |
| -> Hash Join (actual rows=100 loops=1) |
| Hash Cond: (fact1.pid = dim1.pid) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 3 of 262144 buckets. |
| -> Append (actual rows=100 loops=1) |
| Partition Selectors: $0 |
| -> Seq Scan on fact1_1_prt_1_2_prt_ca fact1_1 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_oh fact1_2 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_1_2_prt_wa fact1_3 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_ca fact1_4 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_oh fact1_5 (actual rows=25 loops=1) |
| -> Seq Scan on fact1_1_prt_2_2_prt_wa fact1_6 (actual rows=0 loops=1) |
| -> Seq Scan on fact1_1_prt_3_2_prt_ca fact1_7 (never executed) |
| -> Seq Scan on fact1_1_prt_3_2_prt_oh fact1_8 (never executed) |
| -> Seq Scan on fact1_1_prt_3_2_prt_wa fact1_9 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_ca fact1_10 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_oh fact1_11 (never executed) |
| -> Seq Scan on fact1_1_prt_4_2_prt_wa fact1_12 (never executed) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Partition Selector (selector id: $0) (actual rows=3 loops=1) |
| -> Broadcast Motion 3:3 (slice3; segments: 3) (actual rows=3 loops=1) |
| -> Seq Scan on dim1 (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (31 rows) |
| |
| select fact1.code, count(*) from dim1 inner join fact1 on (dim1.pid=fact1.pid) group by 1 order by 1; |
| code | count |
| ------+------- |
| CA | 50 |
| OH | 50 |
| (2 rows) |
| |
| -- |
| -- multi-attribute list partitioning |
| -- |
| -- Before GPDB 7, we used to support multi-column list partitions natively, |
| -- and these queries did partition elimination. We don't support that anymore, |
| -- but emulate that by using a row expression as the partitioning key. You |
| -- don't get partition elimination with that, however, so these tests are not |
| -- very interesting anymore. |
| -- |
| drop schema if exists dpe_malp cascade; |
| NOTICE: schema "dpe_malp" does not exist, skipping |
| create schema dpe_malp; |
| set search_path='dpe_malp'; |
| set gp_segments_for_planner=2; |
| set optimizer_segments=2; |
| create type malp_key as (i int, j int); |
| create table malp (i int, j int, t text) |
| distributed by (i) |
| partition by list ((row(i, j)::malp_key)); |
| create table malp_p1 partition of malp for values in (row(1, 10)); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table malp_p2 partition of malp for values in (row(2, 20)); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table malp_p3 partition of malp for values in (row(3, 30)); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| insert into malp select 1, 10, 'hello1'; |
| insert into malp select 1, 10, 'hello2'; |
| insert into malp select 1, 10, 'hello3'; |
| insert into malp select 2, 20, 'hello4'; |
| insert into malp select 2, 20, 'hello5'; |
| insert into malp select 3, 30, 'hello6'; |
| create table dim(i int, j int) |
| distributed randomly; |
| insert into dim values(1, 10); |
| analyze malp; |
| analyze dim; |
| -- ORCA doesn't do multi-attribute partitioning currently,so this falls |
| -- back to the Postgres planner |
| explain (costs off, timing off, summary off, analyze) select * from dim inner join malp on (dim.i = malp.i); |
| QUERY PLAN |
| ------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=3 loops=1) |
| -> Hash Join (actual rows=3 loops=1) |
| Hash Cond: (malp.i = dim.i) |
| Extra Text: (seg1) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. |
| -> Append (actual rows=3 loops=1) |
| -> Seq Scan on malp_p1 malp_1 (actual rows=3 loops=1) |
| -> Seq Scan on malp_p2 malp_2 (actual rows=0 loops=1) |
| -> Seq Scan on malp_p3 malp_3 (actual rows=0 loops=1) |
| -> Hash (actual rows=1 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Redistribute Motion 3:3 (slice2; segments: 3) (actual rows=1 loops=1) |
| Hash Key: dim.i |
| -> Seq Scan on dim (actual rows=1 loops=1) |
| Optimizer: Postgres query optimizer |
| (14 rows) |
| |
| set gp_dynamic_partition_pruning = off; |
| select * from dim inner join malp on (dim.i = malp.i); |
| i | j | i | j | t |
| ---+----+---+----+-------- |
| 1 | 10 | 1 | 10 | hello1 |
| 1 | 10 | 1 | 10 | hello2 |
| 1 | 10 | 1 | 10 | hello3 |
| (3 rows) |
| |
| set gp_dynamic_partition_pruning = on; |
| select * from dim inner join malp on (dim.i = malp.i); |
| i | j | i | j | t |
| ---+----+---+----+-------- |
| 1 | 10 | 1 | 10 | hello1 |
| 1 | 10 | 1 | 10 | hello2 |
| 1 | 10 | 1 | 10 | hello3 |
| (3 rows) |
| |
| set gp_dynamic_partition_pruning = on; |
| -- if only the planner was smart enough, one partition would be chosen |
| select * from dim inner join malp on (dim.i = malp.i and dim.j = malp.j); |
| i | j | i | j | t |
| ---+----+---+----+-------- |
| 1 | 10 | 1 | 10 | hello1 |
| 1 | 10 | 1 | 10 | hello2 |
| 1 | 10 | 1 | 10 | hello3 |
| (3 rows) |
| |
| -- |
| -- Plan where the Append that the PartitionSelector affects is not the immediate child |
| -- of the join. |
| -- |
| create table apart (id int4, t text) partition by range (id) (start (1) end (1000) every (200)); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| create table b (id int4, t text); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| create table c (id int4, t text); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| insert into apart select g, g from generate_series(1, 999) g; |
| insert into b select g, g from generate_series(1, 5) g; |
| insert into c select g, g from generate_series(1, 20) g; |
| analyze apart; |
| analyze b; |
| analyze c; |
| set gp_dynamic_partition_pruning = off; |
| explain (costs off, timing off, summary off, analyze) select * from apart as a, b, c where a.t = b.t and a.id = c.id; |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=5 loops=1) |
| -> Hash Join (actual rows=3 loops=1) |
| Hash Cond: (a.id = c.id) |
| Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 8 of 262144 buckets. |
| -> Hash Join (actual rows=3 loops=1) |
| Hash Cond: (a.t = b.t) |
| Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 5 of 262144 buckets. |
| -> Dynamic Seq Scan on apart a (actual rows=70 loops=1) |
| Number of partitions to scan: 5 (out of 5) |
| Partitions scanned: Avg 1.0 x 3 workers. Max 1 parts (seg0). |
| -> Hash (actual rows=5 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=5 loops=1) |
| -> Seq Scan on b (actual rows=3 loops=1) |
| -> Hash (actual rows=8 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Partition Selector (selector id: $0) (actual rows=8 loops=1) |
| -> Seq Scan on c (actual rows=8 loops=1) |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (17 rows) |
| |
| select * from apart as a, b, c where a.t = b.t and a.id = c.id; |
| id | t | id | t | id | t |
| ----+---+----+---+----+--- |
| 3 | 3 | 3 | 3 | 3 | 3 |
| 4 | 4 | 4 | 4 | 4 | 4 |
| 5 | 5 | 5 | 5 | 5 | 5 |
| 1 | 1 | 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 | 2 | 2 |
| (5 rows) |
| |
| set gp_dynamic_partition_pruning = on; |
| explain (costs off, timing off, summary off, analyze) select * from apart as a, b, c where a.t = b.t and a.id = c.id; |
| QUERY PLAN |
| --------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=5 loops=1) |
| -> Hash Join (actual rows=3 loops=1) |
| Hash Cond: (a.id = c.id) |
| Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 8 of 262144 buckets. |
| -> Hash Join (actual rows=3 loops=1) |
| Hash Cond: (a.t = b.t) |
| Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 5 of 262144 buckets. |
| -> Dynamic Seq Scan on apart a (actual rows=70 loops=1) |
| Number of partitions to scan: 5 (out of 5) |
| Partitions scanned: Avg 1.0 x 3 workers. Max 1 parts (seg0). |
| -> Hash (actual rows=5 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Broadcast Motion 3:3 (slice2; segments: 3) (actual rows=5 loops=1) |
| -> Seq Scan on b (actual rows=3 loops=1) |
| -> Hash (actual rows=8 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2049kB |
| -> Partition Selector (selector id: $0) (actual rows=8 loops=1) |
| -> Seq Scan on c (actual rows=8 loops=1) |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (17 rows) |
| |
| select * from apart as a, b, c where a.t = b.t and a.id = c.id; |
| id | t | id | t | id | t |
| ----+---+----+---+----+--- |
| 3 | 3 | 3 | 3 | 3 | 3 |
| 4 | 4 | 4 | 4 | 4 | 4 |
| 5 | 5 | 5 | 5 | 5 | 5 |
| 1 | 1 | 1 | 1 | 1 | 1 |
| 2 | 2 | 2 | 2 | 2 | 2 |
| (5 rows) |
| |
| -- |
| -- DPE: assertion failed with window function |
| -- |
| drop schema if exists dpe_bugs cascade; |
| NOTICE: schema "dpe_bugs" does not exist, skipping |
| create schema dpe_bugs; |
| set search_path='dpe_bugs'; |
| set gp_segments_for_planner=2; |
| set optimizer_segments=2; |
| create table pat(a int, b date) partition by range (b) (start ('2010-01-01') end ('2010-01-05') every (1), default partition other); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| insert into pat select i,date '2010-01-01' + i from generate_series(1, 10)i; |
| create table jpat(a int, b date); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'a' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| insert into jpat values(1, '2010-01-02'); |
| analyze jpat; |
| -- start_ignore |
| -- Known_opt_diff: MPP-21323 |
| -- end_ignore |
| explain (costs off, timing off, summary off, analyze) select * from (select count(*) over (order by a rows between 1 preceding and 1 following), a, b from jpat)jpat inner join pat using(b); |
| QUERY PLAN |
| ------------------------------------------------------------------------------------ |
| Hash Join (actual rows=1 loops=1) |
| Hash Cond: (jpat.b = pat.b) |
| Extra Text: Hash chain length 1.0 avg, 1 max, using 10 of 131072 buckets. |
| -> WindowAgg (actual rows=1 loops=1) |
| Order By: jpat.a |
| -> Gather Motion 3:1 (slice1; segments: 3) (actual rows=1 loops=1) |
| Merge Key: jpat.a |
| -> Sort (actual rows=1 loops=1) |
| Sort Key: jpat.a |
| Sort Method: quicksort Memory: 150kB |
| -> Seq Scan on jpat (actual rows=1 loops=1) |
| -> Hash (actual rows=10 loops=1) |
| Buckets: 131072 Batches: 1 Memory Usage: 1025kB |
| -> Gather Motion 3:1 (slice2; segments: 3) (actual rows=10 loops=1) |
| -> Dynamic Seq Scan on pat (actual rows=5 loops=1) |
| Number of partitions to scan: 5 (out of 5) |
| Partitions scanned: Avg 5.0 x 3 workers. Max 5 parts (seg0). |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (17 rows) |
| |
| select * from (select count(*) over (order by a rows between 1 preceding and 1 following), a, b from jpat)jpat inner join pat using(b); |
| b | count | a | a |
| ------------+-------+---+--- |
| 01-02-2010 | 1 | 1 | 1 |
| (1 row) |
| |
| -- |
| -- Partitioning on an expression |
| -- |
| drop table if exists t; |
| NOTICE: table "t" does not exist, skipping |
| drop table if exists pt; |
| NOTICE: table "pt" does not exist, skipping |
| create table t(id int, b int); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| create table pt(id int, b int) partition by range (id); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| create table pt1 partition of pt for values from (1) to (2); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt2 partition of pt for values from (2) to (3); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt3 partition of pt for values from (3) to (4); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table ptx (id int, b int) partition by list (((b) % 2)); |
| NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' as the Apache Cloudberry data distribution key for this table. |
| HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. |
| create table ptx_even partition of ptx for values in (0); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table ptx_odd partition of ptx for values in (1); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| alter table pt attach partition ptx for values from (4) to (20); |
| insert into t values (1, 1); |
| insert into t values (2, 2); |
| insert into pt select i, i from generate_series(1,7) i; |
| analyze t; |
| analyze pt; |
| -- Prune on the simple partition columns, but not on the expression |
| explain (analyze, costs off, timing off, summary off) |
| select * from pt, t where t.id = pt.id; |
| QUERY PLAN |
| -------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=2 loops=1) |
| -> Hash Join (actual rows=1 loops=1) |
| Hash Cond: (pt.id = t.id) |
| Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. |
| -> Append (actual rows=1 loops=1) |
| Partition Selectors: $0 |
| -> Seq Scan on pt1 pt_1 (actual rows=1 loops=1) |
| -> Seq Scan on pt2 pt_2 (actual rows=1 loops=1) |
| -> Seq Scan on pt3 pt_3 (never executed) |
| -> Seq Scan on ptx_even pt_4 (never executed) |
| -> Seq Scan on ptx_odd pt_5 (never executed) |
| -> Hash (actual rows=1 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=1 loops=1) |
| -> Seq Scan on t (actual rows=1 loops=1) |
| Optimizer: Postgres query optimizer |
| (15 rows) |
| |
| insert into t values (4, 4), (6, 6), (8, 8), (10, 10); |
| explain (analyze, costs off, timing off, summary off) |
| select * from pt, t where t.id = pt.id; |
| QUERY PLAN |
| -------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=4 loops=1) |
| -> Hash Join (actual rows=2 loops=1) |
| Hash Cond: (pt.id = t.id) |
| Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 3 of 524288 buckets. |
| -> Append (actual rows=3 loops=1) |
| Partition Selectors: $0 |
| -> Seq Scan on pt1 pt_1 (actual rows=1 loops=1) |
| -> Seq Scan on pt2 pt_2 (actual rows=1 loops=1) |
| -> Seq Scan on pt3 pt_3 (never executed) |
| -> Seq Scan on ptx_even pt_4 (actual rows=1 loops=1) |
| -> Seq Scan on ptx_odd pt_5 (actual rows=1 loops=1) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=3 loops=1) |
| -> Seq Scan on t (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (15 rows) |
| |
| -- Plan-time pruning based on the 'id' partitioning column, and |
| -- run-time join pruning based on the expression |
| explain (analyze, costs off, timing off, summary off) |
| select * from pt, t where pt.id = 4 and t.id = 4 and (t.b % 2) = (pt.b % 2); |
| QUERY PLAN |
| -------------------------------------------------------------------------------- |
| Gather Motion 1:1 (slice1; segments: 1) (actual rows=1 loops=1) |
| -> Hash Join (actual rows=1 loops=1) |
| Hash Cond: ((pt.b % 2) = (t.b % 2)) |
| Extra Text: Hash chain length 1.0 avg, 1 max, using 1 of 524288 buckets. |
| -> Append (actual rows=1 loops=1) |
| Partition Selectors: $0 |
| -> Seq Scan on ptx_even pt_1 (actual rows=1 loops=1) |
| Filter: (id = 4) |
| -> Seq Scan on ptx_odd pt_2 (never executed) |
| Filter: (id = 4) |
| -> Hash (actual rows=1 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=1 loops=1) |
| -> Seq Scan on t (actual rows=1 loops=1) |
| Filter: (id = 4) |
| Rows Removed by Filter: 2 |
| Optimizer: Postgres query optimizer |
| (16 rows) |
| |
| -- Mixed case |
| insert into pt values (4, 5); |
| explain (analyze, costs off, timing off, summary off) |
| select * from pt, t where t.id = pt.id and (t.b % 2) = (pt.b % 2); |
| QUERY PLAN |
| -------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=4 loops=1) |
| -> Hash Join (actual rows=2 loops=1) |
| Hash Cond: ((pt.id = t.id) AND ((pt.b % 2) = (t.b % 2))) |
| Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 3 of 524288 buckets. |
| -> Append (actual rows=2 loops=1) |
| Partition Selectors: $0 |
| -> Seq Scan on pt1 pt_1 (actual rows=1 loops=1) |
| -> Seq Scan on pt2 pt_2 (actual rows=1 loops=1) |
| -> Seq Scan on pt3 pt_3 (never executed) |
| -> Seq Scan on ptx_even pt_4 (actual rows=1 loops=1) |
| -> Seq Scan on ptx_odd pt_5 (never executed) |
| -> Hash (actual rows=3 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=3 loops=1) |
| -> Seq Scan on t (actual rows=3 loops=1) |
| Optimizer: Postgres query optimizer |
| (15 rows) |
| |
| -- |
| -- Join pruning on an inequality qual |
| -- |
| drop table if exists t; |
| drop table if exists pt; |
| create table t(dist int, tid int) distributed by (dist); |
| create table pt(dist int, ptid int) distributed by (dist) partition by range (ptid); |
| create table pt1 partition of pt for values from (1) to (2); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt2 partition of pt for values from (2) to (3); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt3 partition of pt for values from (3) to (4); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt4 partition of pt for values from (4) to (5); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt5 partition of pt for values from (5) to (6); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table ptdefault partition of pt default; |
| NOTICE: table has parent, setting distribution columns to match parent table |
| insert into t values (0, 4); |
| insert into t values (0, 3); |
| insert into pt select 0, i from generate_series(1,9) i; |
| analyze t; |
| analyze pt; |
| explain (analyze, costs off, timing off, summary off) |
| select * from pt, t where t.dist = pt.dist and t.tid < pt.ptid; |
| QUERY PLAN |
| -------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (actual rows=11 loops=1) |
| -> Hash Join (actual rows=11 loops=1) |
| Hash Cond: (pt.dist = t.dist) |
| Join Filter: (t.tid < pt.ptid) |
| Rows Removed by Join Filter: 3 |
| Extra Text: (seg1) Hash chain length 2.0 avg, 2 max, using 1 of 524288 buckets. |
| -> Dynamic Seq Scan on pt (actual rows=7 loops=1) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: 4 (seg1). |
| -> Hash (actual rows=2 loops=1) |
| Buckets: 524288 Batches: 1 Memory Usage: 4097kB |
| -> Partition Selector (selector id: $0) (actual rows=2 loops=1) |
| -> Seq Scan on t (actual rows=2 loops=1) |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (13 rows) |
| |
| -- |
| -- Test join pruning with a MergeAppend |
| -- |
| drop table if exists t; |
| drop table if exists pt; |
| create table t(dist int, tid int, sk int) distributed by (dist); |
| create table pt(dist int, ptid int, sk int) distributed by (dist) partition by range (ptid); |
| create table pt1 partition of pt for values from (1) to (2); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt2 partition of pt for values from (2) to (3); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt3 partition of pt for values from (3) to (4); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt4 partition of pt for values from (4) to (5); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table pt5 partition of pt for values from (5) to (6); |
| NOTICE: table has parent, setting distribution columns to match parent table |
| create table ptdefault partition of pt default; |
| NOTICE: table has parent, setting distribution columns to match parent table |
| insert into t values (1, 1, 1); |
| insert into t values (2, 2, 2); |
| insert into t select i, i, i from generate_series(5,100) i; |
| insert into pt select i, i, i from generate_series(1,7) i; |
| insert into pt select i, i, i from generate_series(1000, 1100) i; |
| analyze t; |
| analyze pt; |
| create index on pt (ptid, sk); |
| set enable_mergejoin=on; |
| set enable_seqscan=off; |
| -- force_explain |
| explain (analyze, timing off, summary off) |
| select * from pt, t where t.dist = pt.dist and t.tid = pt.ptid order by t.tid, t.sk; |
| QUERY PLAN |
| ----------------------------------------------------------------------------------------------------------------------------- |
| Gather Motion 3:1 (slice1; segments: 3) (cost=0.00..862.10 rows=98 width=24) (actual rows=5 loops=1) |
| Merge Key: t.tid, t.sk |
| -> Sort (cost=0.00..862.09 rows=33 width=24) (actual rows=2 loops=1) |
| Sort Key: t.tid, t.sk |
| Sort Method: quicksort Memory: 75kB |
| -> Hash Join (cost=0.00..862.05 rows=33 width=24) (actual rows=2 loops=1) |
| Hash Cond: ((pt.dist = t.dist) AND (pt.ptid = t.tid)) |
| Extra Text: (seg0) Hash chain length 1.0 avg, 1 max, using 36 of 262144 buckets. |
| -> Dynamic Seq Scan on pt (cost=0.00..431.00 rows=33 width=12) (actual rows=36 loops=1) |
| Number of partitions to scan: 6 (out of 6) |
| Partitions scanned: Avg 2.0 x 3 workers. Max 2 parts (seg0). |
| -> Hash (cost=431.00..431.00 rows=33 width=12) (actual rows=37 loops=1) |
| Buckets: 262144 Batches: 1 Memory Usage: 2050kB |
| -> Partition Selector (selector id: $0) (cost=0.00..431.00 rows=33 width=12) (actual rows=37 loops=1) |
| -> Seq Scan on t (cost=0.00..431.00 rows=33 width=12) (actual rows=37 loops=1) |
| Optimizer: Pivotal Optimizer (GPORCA) |
| (16 rows) |
| |