分区表代码优化。

1.修复分区表剪枝比例的计算。
  2.删除GetPartitionInfo函数中对传入的剪枝结果进行深拷贝的操作。
  3.优化分区表SQLByPass对分区IndexOid的获取。
This commit is contained in:
syj
2021-03-13 16:47:08 +08:00
parent 517c16bba3
commit 23b2a58551
7 changed files with 72 additions and 70 deletions

View File

@ -801,7 +801,7 @@ static void set_plain_rel_size(PlannerInfo* root, RelOptInfo* rel, RangeTblEntry
if (relation->partMap != NULL && PartitionMapIsRange(relation->partMap)) {
RangePartitionMap *partMmap = (RangePartitionMap *)relation->partMap;
pruningRatio = rel->partItrs / partMmap->rangeElementsNum;
pruningRatio = (double)rel->partItrs / partMmap->rangeElementsNum;
}
heap_close(relation, NoLock);

View File

@ -89,7 +89,6 @@ static PartitionMap* GetRelPartitionMap(Relation relation)
*/
PruningResult* GetPartitionInfo(PruningResult* result, EState* estate, Relation current_relation)
{
PruningResult* res = NULL;
PruningResult* resPartition = NULL;
PruningContext context;
@ -100,11 +99,10 @@ PruningResult* GetPartitionInfo(PruningResult* result, EState* estate, Relation
context.estate = estate;
context.relation = current_relation;
res = copyPruningResult(result);
if (current_relation->partMap->type == PART_TYPE_LIST || current_relation->partMap->type == PART_TYPE_HASH) {
resPartition = partitionEqualPruningWalker(current_relation->partMap->type, res->expr, &context);
resPartition = partitionEqualPruningWalker(current_relation->partMap->type, result->expr, &context);
} else {
resPartition = partitionPruningWalker(res->expr, &context);
resPartition = partitionPruningWalker(result->expr, &context);
}
partitionPruningFromBoundary(&context, resPartition);
if (PruningResultIsFull(resPartition) ||

View File

@ -353,10 +353,15 @@ Oid GetRelOidForPartitionTable(Scan scan, const Relation rel, ParamListInfo para
}
/* init the index in construct */
Relation InitPartitionIndexInFusion(Oid parentIndexOid, Oid partOid, Partition* partIndex, Relation* parentIndex)
Relation InitPartitionIndexInFusion(Oid parentIndexOid, Oid partOid, Partition* partIndex, Relation* parentIndex, Relation rel)
{
*parentIndex = relation_open(parentIndexOid, AccessShareLock);
Oid partIndexOid = getPartitionIndexOid(parentIndexOid, partOid);
Oid partIndexOid;
if (list_length(rel->rd_indexlist) == 1) {
partIndexOid = lfirst_oid(rel->rd_indexlist->head);
} else {
partIndexOid = getPartitionIndexOid(parentIndexOid, partOid);
}
*partIndex = partitionOpen(*parentIndex, partIndexOid, AccessShareLock);
Relation index = partitionGetRelation(*parentIndex, *partIndex);
return index;
@ -481,7 +486,7 @@ void IndexScanFusion::Init(long max_rows)
/* get partition index */
Oid parentIndexOid = m_node->indexid;
m_index = InitPartitionIndexInFusion(parentIndexOid, m_reloid, &m_partIndex, &m_parentIndex);
m_index = InitPartitionIndexInFusion(parentIndexOid, m_reloid, &m_partIndex, &m_parentIndex, m_rel);
} else {
m_rel = heap_open(m_reloid, AccessShareLock);
m_index = index_open(m_node->indexid, AccessShareLock);
@ -682,7 +687,7 @@ IndexOnlyScanFusion::IndexOnlyScanFusion(IndexOnlyScan* node, PlannedStmt* plans
/* get Partition index */
Oid parentIndexOid = m_node->indexid;
m_index = InitPartitionIndexInFusion(parentIndexOid, m_reloid, &m_partIndex, &m_parentIndex);
m_index = InitPartitionIndexInFusion(parentIndexOid, m_reloid, &m_partIndex, &m_parentIndex, m_rel);
} else {
m_reloid = getrelid(m_node->scan.scanrelid, planstmt->rtable);
m_index = index_open(m_node->indexid, AccessShareLock);
@ -721,7 +726,7 @@ void IndexOnlyScanFusion::Init(long max_rows)
/* get partition index */
Oid parentIndexOid = m_node->indexid;
m_index = InitPartitionIndexInFusion(parentIndexOid, m_reloid, &m_partIndex, &m_parentIndex);
m_index = InitPartitionIndexInFusion(parentIndexOid, m_reloid, &m_partIndex, &m_parentIndex, m_rel);
} else {
m_rel = heap_open(m_reloid, AccessShareLock);
m_index = index_open(m_node->indexid, AccessShareLock);

View File

@ -227,11 +227,11 @@ Number of partition: 5 (View pg_partition to check each partition range.)
insert into test_gpi_create_like values(generate_series(0,9999), 1);
explain (costs off) select * from test_gpi_create_like where c1 = 0;
QUERY PLAN
--------------------------------------------------------------------
QUERY PLAN
-----------------------------------------------------------------
Bitmap Heap Scan on test_gpi_create_like
Recheck Cond: (c1 = 0)
-> Bitmap Index Scan on test_gpi_create_like_c1_c2_tableoid_idx
-> Bitmap Index Scan on test_gpi_create_like_c1_tableoid_idx
Index Cond: (c1 = 0)
(4 rows)

View File

@ -21,9 +21,9 @@ select a.relname,a.parttype,a.reloptions from pg_partition a, pg_class b where a
(2 rows)
explain (costs off) select * from test_gpi_more_invalid where a >= 3000;
QUERY PLAN
------------------------------------------------------------------------------------
Index Only Scan using global_index_gpi_more_invalid_a_b_c on test_gpi_more_invalid
QUERY PLAN
---------------------------------------------------------------------------
Index Scan using global_index_gpi_more_invalid_b on test_gpi_more_invalid
Index Cond: (a >= 3000)
(2 rows)
@ -55,10 +55,10 @@ explain (costs off) select count(*) from test_gpi_more_invalid where a <= 100 an
(4 rows)
explain (costs off) select count(*) from test_gpi_more_invalid where a > 3000;
QUERY PLAN
------------------------------------------------------------------------------------------
QUERY PLAN
--------------------------------------------------------------------------------------
Aggregate
-> Index Only Scan using global_index_gpi_more_invalid_a_b_c on test_gpi_more_invalid
-> Index Only Scan using global_index_gpi_more_invalid_b on test_gpi_more_invalid
Index Cond: (a > 3000)
(3 rows)

View File

@ -119,11 +119,12 @@ select * from gpi_index_test where a < 200 and b > 190 order by a;
-- multi column index with global index
create index gpi_index_test_global_a_b on gpi_index_test(a,b) global;
explain (costs off) select * from gpi_index_test where a = 200 and b = 100;
QUERY PLAN
--------------------------------------------------------------
Index Scan using gpi_index_test_global_a_b on gpi_index_test
Index Cond: ((a = 200) AND (b = 100))
(2 rows)
QUERY PLAN
------------------------------------------------------------
Index Scan using gpi_index_test_global_b on gpi_index_test
Index Cond: (b = 100)
Filter: (a = 200)
(3 rows)
select * from gpi_index_test where a = 100 and b = 100 order by a;
a | b | c
@ -432,19 +433,17 @@ select count(*) from gpi_index_test as t1 NATURAL inner join gpi_index_test1 t2
(1 row)
explain (costs off) select * from gpi_index_test t1 full join gpi_index_test1 t2 on t1.b >= t2.a where t1.b < 200 and t2.a = 50 and t1.a = 100;
QUERY PLAN
--------------------------------------------------------------------------------------
QUERY PLAN
-----------------------------------------------------------------------
Nested Loop
Join Filter: (t1.b >= t2.a)
-> Partition Iterator
Iterations: 1
-> Partitioned Index Scan using gpi_index_test_local_a on gpi_index_test t1
Index Cond: (a = 100)
Filter: (b < 200)
Selected Partitions: 2
-> Index Scan using gpi_index_test1_global_a on gpi_index_test1 t2
Index Cond: (a = 50)
(10 rows)
-> Bitmap Heap Scan on gpi_index_test t1
Recheck Cond: ((b >= t2.a) AND (b < 200))
Filter: (a = 100)
-> Bitmap Index Scan on gpi_index_test_global_b
Index Cond: ((b >= t2.a) AND (b < 200))
(8 rows)
select * from gpi_index_test t1 full join gpi_index_test1 t2 on t1.b >= t2.a where t1.b < 200 and t2.a = 50 and t1.a = 100;
a | b | c | a | b | c
@ -470,15 +469,15 @@ select count(*) from gpi_index_test t1 left join gpi_index_test1 t2 on (t1.b >=
(1 row)
explain (costs off) select * from gpi_index_test t1 right join gpi_index_test1 t2 on (t1.b >= t2.a and (t1.a < 60 or t2.b != 30)) where t1.b < 200 and t2.a < 100;
QUERY PLAN
-----------------------------------------------------------------------------
QUERY PLAN
---------------------------------------------------------------------------
Nested Loop
Join Filter: ((t1.b >= t2.a) AND ((t1.a < 60) OR (t2.b <> 30)))
-> Index Scan using gpi_index_test_global_b on gpi_index_test t1
Index Cond: (b < 200)
-> Index Scan using gpi_index_test1_global_a on gpi_index_test1 t2
Index Cond: (a < 100)
-> Materialize
-> Index Scan using gpi_index_test1_global_a on gpi_index_test1 t2
Index Cond: (a < 100)
-> Index Scan using gpi_index_test_global_b on gpi_index_test t1
Index Cond: (b < 200)
(7 rows)
select count(*) from gpi_index_test t1 left join gpi_index_test1 t2 on (t1.b >= t2.a and (t1.a != 60 or t1.b != 30)) where t1.b < 200 and t2.a < 100;

View File

@ -1299,9 +1299,9 @@ explain select col1,col2 from test_bypass_sql_partition where col1=10 and col2=1
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------
[Bypass]
Partition Iterator (cost=10000000000.00..1000000000827.00 rows=1 width=8)
Partition Iterator (cost=10000000000.00..1000000000827.01 rows=1 width=8)
Iterations: 1
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000000827.00 rows=1 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000000827.01 rows=1 width=8)
Index Cond: ((col1 = 10) AND (col2 = 10))
Selected Partitions: 2
(6 rows)
@ -1316,10 +1316,10 @@ explain select col1,col2 from test_bypass_sql_partition where col1=10 and col2=1
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------
[Bypass]
Limit (cost=10000000000.00..1000000000827.00 rows=1 width=8)
-> Partition Iterator (cost=10000000000.00..1000000000827.00 rows=1 width=8)
Limit (cost=10000000000.00..1000000000827.01 rows=1 width=8)
-> Partition Iterator (cost=10000000000.00..1000000000827.01 rows=1 width=8)
Iterations: 1
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000000827.00 rows=1 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000000827.01 rows=1 width=8)
Index Cond: ((col1 = 10) AND (col2 = 10))
Selected Partitions: 2
(7 rows)
@ -1334,10 +1334,10 @@ explain select col1,col2 from test_bypass_sql_partition where col1=10 and col2=1
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------
[Bypass]
Limit (cost=10000000000.00..1000000000827.00 rows=1 width=8)
-> Partition Iterator (cost=10000000000.00..1000000000827.00 rows=1 width=8)
Limit (cost=10000000000.00..1000000000827.01 rows=1 width=8)
-> Partition Iterator (cost=10000000000.00..1000000000827.01 rows=1 width=8)
Iterations: 1
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000000827.00 rows=1 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000000827.01 rows=1 width=8)
Index Cond: ((col1 = 10) AND (col2 = 10))
Selected Partitions: 2
(7 rows)
@ -1414,10 +1414,10 @@ explain select col1, col2 from test_bypass_sql_partition where col1 <= 30 and co
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
[No Bypass]reason: Bypass not support query in multiple partitions.
Limit (cost=0.00..24.37 rows=6 width=8)
-> Partition Iterator (cost=0.00..24.37 rows=6 width=8)
Limit (cost=0.00..28.37 rows=6 width=8)
-> Partition Iterator (cost=0.00..28.37 rows=6 width=8)
Iterations: 3
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=0.00..24.37 rows=6 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=0.00..28.37 rows=6 width=8)
Index Cond: ((col1 <= 30) AND (col1 >= 10))
Selected Partitions: 2..4
(7 rows)
@ -1494,10 +1494,10 @@ explain select col1, col2 from test_bypass_sql_partition where col1 < 20 order b
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------
[No Bypass]reason: Bypass not support query in multiple partitions.
Limit (cost=0.00..1.42 rows=10 width=8)
-> Partition Iterator (cost=0.00..55.06 rows=389 width=8)
Limit (cost=0.00..1.83 rows=10 width=8)
-> Partition Iterator (cost=0.00..71.06 rows=389 width=8)
Iterations: 2
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=0.00..55.06 rows=389 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=0.00..71.06 rows=389 width=8)
Index Cond: (col1 < 20)
Selected Partitions: 1..2
(7 rows)
@ -1902,9 +1902,9 @@ explain select col1,col2 from test_bypass_sql_partition where col1=0 order by c
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------
[Bypass]
Partition Iterator (cost=10000000000.00..1000000002435.50 rows=6 width=8)
Partition Iterator (cost=10000000000.00..1000000002435.51 rows=6 width=8)
Iterations: 1
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000002435.50 rows=6 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000002435.51 rows=6 width=8)
Index Cond: (col1 = 0)
Selected Partitions: 1
(6 rows)
@ -1929,10 +1929,10 @@ explain select col1,col2 from test_bypass_sql_partition where col1>0 and col1<10
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------
[Bypass]
Limit (cost=10000000000.00..1000000002437.00 rows=6 width=8)
-> Partition Iterator (cost=10000000000.00..1000000002437.00 rows=6 width=8)
Limit (cost=10000000000.00..1000000002437.01 rows=6 width=8)
-> Partition Iterator (cost=10000000000.00..1000000002437.01 rows=6 width=8)
Iterations: 1
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000002437.00 rows=6 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000002437.01 rows=6 width=8)
Index Cond: ((col1 > 0) AND (col1 < 10))
Selected Partitions: 1
(7 rows)
@ -1957,9 +1957,9 @@ explain select col2,col1 from test_bypass_sql_partition where col1>0 and col1<10
---------------------------------------------------------------------------------------------------------------------------------------------------------------
[Bypass]
Limit (cost=10000000000.00..505000001218.50 rows=3 width=8)
-> Partition Iterator (cost=10000000000.00..1000000002437.00 rows=6 width=8)
-> Partition Iterator (cost=10000000000.00..1000000002437.01 rows=6 width=8)
Iterations: 1
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000002437.00 rows=6 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000002437.01 rows=6 width=8)
Index Cond: ((col1 > 0) AND (col1 < 10))
Selected Partitions: 1
(7 rows)
@ -1976,10 +1976,10 @@ explain select col1,col2 from test_bypass_sql_partition where col1>=0 and col1<1
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------
[Bypass]
Limit (cost=10000000000.00..1000000001234.50 rows=2 width=8)
-> Partition Iterator (cost=10000000000.00..1000000001234.50 rows=2 width=8)
Limit (cost=10000000000.00..1000000001234.51 rows=2 width=8)
-> Partition Iterator (cost=10000000000.00..1000000001234.51 rows=2 width=8)
Iterations: 1
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000001234.50 rows=2 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000001234.51 rows=2 width=8)
Index Cond: ((col1 >= 0) AND (col1 < 10) AND (col2 > 0))
Selected Partitions: 1
(7 rows)
@ -1996,10 +1996,10 @@ explain select col1,col2 from test_bypass_sql_partition where col1>=0 and col1<1
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------
[Bypass]
Limit (cost=10000000000.00..1000000001234.50 rows=2 width=8)
-> Partition Iterator (cost=10000000000.00..1000000001234.50 rows=2 width=8)
Limit (cost=10000000000.00..1000000001234.51 rows=2 width=8)
-> Partition Iterator (cost=10000000000.00..1000000001234.51 rows=2 width=8)
Iterations: 1
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000001234.50 rows=2 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000001234.51 rows=2 width=8)
Index Cond: ((col1 >= 0) AND (col1 < 10) AND (col2 > 0))
Selected Partitions: 1
(7 rows)
@ -2177,10 +2177,10 @@ explain select col1,col2 from test_bypass_sql_partition where col1>=0 and col1<=
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------
[No Bypass]reason: Bypass not support query in multiple partitions.
Limit (cost=10000000000.00..1000000001234.50 rows=2 width=8)
-> Partition Iterator (cost=10000000000.00..1000000001234.50 rows=2 width=8)
Limit (cost=10000000000.00..1000000001234.52 rows=2 width=8)
-> Partition Iterator (cost=10000000000.00..1000000001234.52 rows=2 width=8)
Iterations: 2
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000001234.50 rows=2 width=8)
-> Partitioned Index Only Scan using itest_bypass_sql_partition on test_bypass_sql_partition (cost=10000000000.00..1000000001234.52 rows=2 width=8)
Index Cond: ((col1 >= 0) AND (col1 <= 10) AND (col2 > 0))
Selected Partitions: 1..2
(7 rows)