Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0414b26

Browse files
committed
Add optimizer and executor support for parallel index-only scans.
Commit5262f7a added similar supportfor parallel index scans; this extends that work to index-only scans.As with parallel index scans, this requires support from the index AM,so currently parallel index-only scans will only be possible for btreeindexes.Rafia Sabih, reviewed and tested by Rahila Syed, Tushar Ahuja,and Amit KapilaDiscussion:http://postgr.es/m/CAOGQiiPEAs4C=TBp0XShxBvnWXuzGL2u++Hm1=qnCpd6_Mf8Fw@mail.gmail.com
1 parent16be2fd commit0414b26

File tree

7 files changed

+191
-26
lines changed

7 files changed

+191
-26
lines changed

‎src/backend/executor/execParallel.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include"executor/nodeForeignscan.h"
3030
#include"executor/nodeSeqscan.h"
3131
#include"executor/nodeIndexscan.h"
32+
#include"executor/nodeIndexonlyscan.h"
3233
#include"executor/tqueue.h"
3334
#include"nodes/nodeFuncs.h"
3435
#include"optimizer/planmain.h"
@@ -202,6 +203,10 @@ ExecParallelEstimate(PlanState *planstate, ExecParallelEstimateContext *e)
202203
ExecIndexScanEstimate((IndexScanState*)planstate,
203204
e->pcxt);
204205
break;
206+
caseT_IndexOnlyScanState:
207+
ExecIndexOnlyScanEstimate((IndexOnlyScanState*)planstate,
208+
e->pcxt);
209+
break;
205210
caseT_ForeignScanState:
206211
ExecForeignScanEstimate((ForeignScanState*)planstate,
207212
e->pcxt);
@@ -258,6 +263,10 @@ ExecParallelInitializeDSM(PlanState *planstate,
258263
ExecIndexScanInitializeDSM((IndexScanState*)planstate,
259264
d->pcxt);
260265
break;
266+
caseT_IndexOnlyScanState:
267+
ExecIndexOnlyScanInitializeDSM((IndexOnlyScanState*)planstate,
268+
d->pcxt);
269+
break;
261270
caseT_ForeignScanState:
262271
ExecForeignScanInitializeDSM((ForeignScanState*)planstate,
263272
d->pcxt);
@@ -737,6 +746,9 @@ ExecParallelInitializeWorker(PlanState *planstate, shm_toc *toc)
737746
caseT_IndexScanState:
738747
ExecIndexScanInitializeWorker((IndexScanState*)planstate,toc);
739748
break;
749+
caseT_IndexOnlyScanState:
750+
ExecIndexOnlyScanInitializeWorker((IndexOnlyScanState*)planstate,toc);
751+
break;
740752
caseT_ForeignScanState:
741753
ExecForeignScanInitializeWorker((ForeignScanState*)planstate,
742754
toc);

‎src/backend/executor/nodeIndexonlyscan.c

Lines changed: 135 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121
*ExecEndIndexOnlyScanreleases all storage.
2222
*ExecIndexOnlyMarkPosmarks scan position.
2323
*ExecIndexOnlyRestrPosrestores scan position.
24+
*ExecIndexOnlyScanEstimateestimates DSM space needed for
25+
*parallel index-only scan
26+
*ExecIndexOnlyScanInitializeDSMinitialize DSM for parallel
27+
*index-only scan
28+
*ExecIndexOnlyScanInitializeWorker attach to DSM info in parallel worker
2429
*/
2530
#include"postgres.h"
2631

@@ -277,6 +282,16 @@ ExecIndexOnlyScan(IndexOnlyScanState *node)
277282
void
278283
ExecReScanIndexOnlyScan(IndexOnlyScanState*node)
279284
{
285+
boolreset_parallel_scan= true;
286+
287+
/*
288+
* If we are here to just update the scan keys, then don't reset parallel
289+
* scan. For detailed reason behind this look in the comments for
290+
* ExecReScanIndexScan.
291+
*/
292+
if (node->ioss_NumRuntimeKeys!=0&& !node->ioss_RuntimeKeysReady)
293+
reset_parallel_scan= false;
294+
280295
/*
281296
* If we are doing runtime key calculations (ie, any of the index key
282297
* values weren't simple Consts), compute the new key values. But first,
@@ -296,10 +311,16 @@ ExecReScanIndexOnlyScan(IndexOnlyScanState *node)
296311
node->ioss_RuntimeKeysReady= true;
297312

298313
/* reset index scan */
299-
index_rescan(node->ioss_ScanDesc,
300-
node->ioss_ScanKeys,node->ioss_NumScanKeys,
301-
node->ioss_OrderByKeys,node->ioss_NumOrderByKeys);
314+
if (node->ioss_ScanDesc)
315+
{
316+
317+
index_rescan(node->ioss_ScanDesc,
318+
node->ioss_ScanKeys,node->ioss_NumScanKeys,
319+
node->ioss_OrderByKeys,node->ioss_NumOrderByKeys);
302320

321+
if (reset_parallel_scan&&node->ioss_ScanDesc->parallel_scan)
322+
index_parallelrescan(node->ioss_ScanDesc);
323+
}
303324
ExecScanReScan(&node->ss);
304325
}
305326

@@ -536,29 +557,124 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
536557
/*
537558
* Initialize scan descriptor.
538559
*/
539-
indexstate->ioss_ScanDesc=index_beginscan(currentRelation,
540-
indexstate->ioss_RelationDesc,
541-
estate->es_snapshot,
560+
if (!node->scan.plan.parallel_aware)
561+
{
562+
indexstate->ioss_ScanDesc=index_beginscan(currentRelation,
563+
indexstate->ioss_RelationDesc,
564+
estate->es_snapshot,
542565
indexstate->ioss_NumScanKeys,
543566
indexstate->ioss_NumOrderByKeys);
544567

545-
/* Set it up for index-only scan */
546-
indexstate->ioss_ScanDesc->xs_want_itup= true;
547-
indexstate->ioss_VMBuffer=InvalidBuffer;
548568

549-
/*
550-
* If no run-time keys to calculate, go ahead and pass the scankeys to the
551-
* index AM.
552-
*/
553-
if (indexstate->ioss_NumRuntimeKeys==0)
554-
index_rescan(indexstate->ioss_ScanDesc,
555-
indexstate->ioss_ScanKeys,
556-
indexstate->ioss_NumScanKeys,
557-
indexstate->ioss_OrderByKeys,
558-
indexstate->ioss_NumOrderByKeys);
569+
/* Set it up for index-only scan */
570+
indexstate->ioss_ScanDesc->xs_want_itup= true;
571+
indexstate->ioss_VMBuffer=InvalidBuffer;
572+
573+
/*
574+
* If no run-time keys to calculate, go ahead and pass the scankeys to
575+
* the index AM.
576+
*/
577+
if (indexstate->ioss_NumRuntimeKeys==0)
578+
index_rescan(indexstate->ioss_ScanDesc,
579+
indexstate->ioss_ScanKeys,
580+
indexstate->ioss_NumScanKeys,
581+
indexstate->ioss_OrderByKeys,
582+
indexstate->ioss_NumOrderByKeys);
583+
}
559584

560585
/*
561586
* all done.
562587
*/
563588
returnindexstate;
564589
}
590+
591+
/* ----------------------------------------------------------------
592+
*Parallel Index-only Scan Support
593+
* ----------------------------------------------------------------
594+
*/
595+
596+
/* ----------------------------------------------------------------
597+
*ExecIndexOnlyScanEstimate
598+
*
599+
*estimates the space required to serialize index-only scan node.
600+
* ----------------------------------------------------------------
601+
*/
602+
void
603+
ExecIndexOnlyScanEstimate(IndexOnlyScanState*node,
604+
ParallelContext*pcxt)
605+
{
606+
EState*estate=node->ss.ps.state;
607+
608+
node->ioss_PscanLen=index_parallelscan_estimate(node->ioss_RelationDesc,
609+
estate->es_snapshot);
610+
shm_toc_estimate_chunk(&pcxt->estimator,node->ioss_PscanLen);
611+
shm_toc_estimate_keys(&pcxt->estimator,1);
612+
}
613+
614+
/* ----------------------------------------------------------------
615+
*ExecIndexOnlyScanInitializeDSM
616+
*
617+
*Set up a parallel index-only scan descriptor.
618+
* ----------------------------------------------------------------
619+
*/
620+
void
621+
ExecIndexOnlyScanInitializeDSM(IndexOnlyScanState*node,
622+
ParallelContext*pcxt)
623+
{
624+
EState*estate=node->ss.ps.state;
625+
ParallelIndexScanDescpiscan;
626+
627+
piscan=shm_toc_allocate(pcxt->toc,node->ioss_PscanLen);
628+
index_parallelscan_initialize(node->ss.ss_currentRelation,
629+
node->ioss_RelationDesc,
630+
estate->es_snapshot,
631+
piscan);
632+
shm_toc_insert(pcxt->toc,node->ss.ps.plan->plan_node_id,piscan);
633+
node->ioss_ScanDesc=
634+
index_beginscan_parallel(node->ss.ss_currentRelation,
635+
node->ioss_RelationDesc,
636+
node->ioss_NumScanKeys,
637+
node->ioss_NumOrderByKeys,
638+
piscan);
639+
node->ioss_ScanDesc->xs_want_itup= true;
640+
node->ioss_VMBuffer=InvalidBuffer;
641+
642+
/*
643+
* If no run-time keys to calculate, go ahead and pass the scankeys to
644+
* the index AM.
645+
*/
646+
if (node->ioss_NumRuntimeKeys==0)
647+
index_rescan(node->ioss_ScanDesc,
648+
node->ioss_ScanKeys,node->ioss_NumScanKeys,
649+
node->ioss_OrderByKeys,node->ioss_NumOrderByKeys);
650+
}
651+
652+
/* ----------------------------------------------------------------
653+
*ExecIndexOnlyScanInitializeWorker
654+
*
655+
*Copy relevant information from TOC into planstate.
656+
* ----------------------------------------------------------------
657+
*/
658+
void
659+
ExecIndexOnlyScanInitializeWorker(IndexOnlyScanState*node,shm_toc*toc)
660+
{
661+
ParallelIndexScanDescpiscan;
662+
663+
piscan=shm_toc_lookup(toc,node->ss.ps.plan->plan_node_id);
664+
node->ioss_ScanDesc=
665+
index_beginscan_parallel(node->ss.ss_currentRelation,
666+
node->ioss_RelationDesc,
667+
node->ioss_NumScanKeys,
668+
node->ioss_NumOrderByKeys,
669+
piscan);
670+
node->ioss_ScanDesc->xs_want_itup= true;
671+
672+
/*
673+
* If no run-time keys to calculate, go ahead and pass the scankeys to the
674+
* index AM.
675+
*/
676+
if (node->ioss_NumRuntimeKeys==0)
677+
index_rescan(node->ioss_ScanDesc,
678+
node->ioss_ScanKeys,node->ioss_NumScanKeys,
679+
node->ioss_OrderByKeys,node->ioss_NumOrderByKeys);
680+
}

‎src/backend/optimizer/path/indxpath.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,9 +1048,9 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel,
10481048

10491049
/*
10501050
* If appropriate, consider parallel index scan. We don't allow
1051-
* parallel index scan for bitmaporindex only scans.
1051+
* parallel index scan for bitmap index scans.
10521052
*/
1053-
if (index->amcanparallel&& !index_only_scan&&
1053+
if (index->amcanparallel&&
10541054
rel->consider_parallel&&outer_relids==NULL&&
10551055
scantype!=ST_BITMAPSCAN)
10561056
{
@@ -1104,7 +1104,7 @@ build_index_paths(PlannerInfo *root, RelOptInfo *rel,
11041104
result=lappend(result,ipath);
11051105

11061106
/* If appropriate, consider parallel index scan */
1107-
if (index->amcanparallel&& !index_only_scan&&
1107+
if (index->amcanparallel&&
11081108
rel->consider_parallel&&outer_relids==NULL&&
11091109
scantype!=ST_BITMAPSCAN)
11101110
{

‎src/include/executor/nodeIndexonlyscan.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#defineNODEINDEXONLYSCAN_H
1616

1717
#include"nodes/execnodes.h"
18+
#include"access/parallel.h"
1819

1920
externIndexOnlyScanState*ExecInitIndexOnlyScan(IndexOnlyScan*node,EState*estate,inteflags);
2021
externTupleTableSlot*ExecIndexOnlyScan(IndexOnlyScanState*node);
@@ -23,4 +24,12 @@ extern void ExecIndexOnlyMarkPos(IndexOnlyScanState *node);
2324
externvoidExecIndexOnlyRestrPos(IndexOnlyScanState*node);
2425
externvoidExecReScanIndexOnlyScan(IndexOnlyScanState*node);
2526

27+
/* Support functions for parallel index-only scans */
28+
externvoidExecIndexOnlyScanEstimate(IndexOnlyScanState*node,
29+
ParallelContext*pcxt);
30+
externvoidExecIndexOnlyScanInitializeDSM(IndexOnlyScanState*node,
31+
ParallelContext*pcxt);
32+
externvoidExecIndexOnlyScanInitializeWorker(IndexOnlyScanState*node,
33+
shm_toc*toc);
34+
2635
#endif/* NODEINDEXONLYSCAN_H */

‎src/include/nodes/execnodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1409,6 +1409,7 @@ typedef struct IndexScanState
14091409
*ScanDesc index scan descriptor
14101410
*VMBuffer buffer in use for visibility map testing, if any
14111411
*HeapFetches number of tuples we were forced to fetch from heap
1412+
*ioss_PscanLen Size of parallel index-only scan descriptor
14121413
* ----------------
14131414
*/
14141415
typedefstructIndexOnlyScanState
@@ -1427,6 +1428,7 @@ typedef struct IndexOnlyScanState
14271428
IndexScanDescioss_ScanDesc;
14281429
Bufferioss_VMBuffer;
14291430
longioss_HeapFetches;
1431+
Sizeioss_PscanLen;
14301432
}IndexOnlyScanState;
14311433

14321434
/* ----------------

‎src/test/regress/expected/select_parallel.out

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,14 @@ explain (costs off)
9292
explain (costs off)
9393
select sum(parallel_restricted(unique1)) from tenk1
9494
group by(parallel_restricted(unique1));
95-
QUERY PLAN
96-
----------------------------------------------------
95+
QUERY PLAN
96+
-------------------------------------------------------------------
9797
HashAggregate
9898
Group Key: parallel_restricted(unique1)
99-
-> Index Only Scan using tenk1_unique1 on tenk1
100-
(3 rows)
99+
-> Gather
100+
Workers Planned: 4
101+
-> Parallel Index Only Scan using tenk1_unique1 on tenk1
102+
(5 rows)
101103

102104
-- test parallel plans for queries containing un-correlated subplans.
103105
alter table tenk2 set (parallel_workers = 0);
@@ -146,6 +148,25 @@ select count((unique1)) from tenk1 where hundred > 1;
146148
9800
147149
(1 row)
148150

151+
-- test parallel index-only scans.
152+
explain (costs off)
153+
select count(*) from tenk1 where thousand > 95;
154+
QUERY PLAN
155+
--------------------------------------------------------------------------------
156+
Finalize Aggregate
157+
-> Gather
158+
Workers Planned: 4
159+
-> Partial Aggregate
160+
-> Parallel Index Only Scan using tenk1_thous_tenthous on tenk1
161+
Index Cond: (thousand > 95)
162+
(6 rows)
163+
164+
select count(*) from tenk1 where thousand > 95;
165+
count
166+
-------
167+
9040
168+
(1 row)
169+
149170
reset enable_seqscan;
150171
reset enable_bitmapscan;
151172
set force_parallel_mode=1;

‎src/test/regress/sql/select_parallel.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ explain (costs off)
5656
selectcount((unique1))from tenk1where hundred>1;
5757
selectcount((unique1))from tenk1where hundred>1;
5858

59+
-- test parallel index-only scans.
60+
explain (costs off)
61+
selectcount(*)from tenk1where thousand>95;
62+
selectcount(*)from tenk1where thousand>95;
63+
5964
reset enable_seqscan;
6065
reset enable_bitmapscan;
6166

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp