Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2609e91

Browse files
committed
Fix regression in parallel planning against inheritance tables.
Commit 51ee6f3 accidentally changed the behavior around inheritance hierarchies; before, we always considered parallel paths even for very small inheritance children, because otherwise an inheritance hierarchy with even one small child wouldn't be eligible for parallelism. That exception was inadverently removed; put it back. In passing, also adjust the degree-of-parallelism comptuation for index-only scans not to consider the number of heap pages fetched. Otherwise, we'll avoid parallel index-only scans on tables that are mostly all-visible, which isn't especially logical. Robert Haas and Amit Kapila, per a report from Ashutosh Sharma. Discussion: http://postgr.es/m/CAE9k0PmgSoOHRd60SHu09aRVTHRSs8s6pmyhJKWHxWw9C_x+XA@mail.gmail.com
1 parent c11453c commit 2609e91

File tree

3 files changed

+36
-25
lines changed

3 files changed

+36
-25
lines changed

src/backend/optimizer/path/allpaths.c

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ create_plain_partial_paths(PlannerInfo *root, RelOptInfo *rel)
692692
{
693693
int parallel_workers;
694694

695-
parallel_workers = compute_parallel_worker(rel, rel->pages, 0);
695+
parallel_workers = compute_parallel_worker(rel, rel->pages, -1);
696696

697697
/* If any limit was set to zero, the user doesn't want a parallel scan. */
698698
if (parallel_workers <= 0)
@@ -2938,7 +2938,7 @@ create_partial_bitmap_paths(PlannerInfo *root, RelOptInfo *rel,
29382938
pages_fetched = compute_bitmap_pages(root, rel, bitmapqual, 1.0,
29392939
NULL, NULL);
29402940

2941-
parallel_workers = compute_parallel_worker(rel, pages_fetched, 0);
2941+
parallel_workers = compute_parallel_worker(rel, pages_fetched, -1);
29422942

29432943
if (parallel_workers <= 0)
29442944
return;
@@ -2953,16 +2953,16 @@ create_partial_bitmap_paths(PlannerInfo *root, RelOptInfo *rel,
29532953
* be scanned and the size of the index to be scanned, then choose a minimum
29542954
* of those.
29552955
*
2956-
* "heap_pages" is the number of pages from the table that we expect to scan.
2957-
* "index_pages" is the number of pages from the index that we expect to scan.
2956+
* "heap_pages" is the number of pages from the table that we expect to scan, or
2957+
* -1 if we don't expect to scan any.
2958+
*
2959+
* "index_pages" is the number of pages from the index that we expect to scan, or
2960+
* -1 if we don't expect to scan any.
29582961
*/
29592962
int
2960-
compute_parallel_worker(RelOptInfo *rel, BlockNumber heap_pages,
2961-
BlockNumber index_pages)
2963+
compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages)
29622964
{
29632965
int parallel_workers = 0;
2964-
int heap_parallel_workers = 1;
2965-
int index_parallel_workers = 1;
29662966

29672967
/*
29682968
* If the user has set the parallel_workers reloption, use that; otherwise
@@ -2972,23 +2972,24 @@ compute_parallel_worker(RelOptInfo *rel, BlockNumber heap_pages,
29722972
parallel_workers = rel->rel_parallel_workers;
29732973
else
29742974
{
2975-
int heap_parallel_threshold;
2976-
int index_parallel_threshold;
2977-
29782975
/*
2979-
* If this relation is too small to be worth a parallel scan, just
2980-
* return without doing anything ... unless it's an inheritance child.
2981-
* In that case, we want to generate a parallel path here anyway. It
2982-
* might not be worthwhile just for this relation, but when combined
2983-
* with all of its inheritance siblings it may well pay off.
2976+
* If the number of pages being scanned is insufficient to justify a
2977+
* parallel scan, just return zero ... unless it's an inheritance
2978+
* child. In that case, we want to generate a parallel path here
2979+
* anyway. It might not be worthwhile just for this relation, but
2980+
* when combined with all of its inheritance siblings it may well pay
2981+
* off.
29842982
*/
2985-
if (heap_pages < (BlockNumber) min_parallel_table_scan_size &&
2986-
index_pages < (BlockNumber) min_parallel_index_scan_size &&
2987-
rel->reloptkind == RELOPT_BASEREL)
2983+
if (rel->reloptkind == RELOPT_BASEREL &&
2984+
((heap_pages >= 0 && heap_pages < min_parallel_table_scan_size) ||
2985+
(index_pages >= 0 && index_pages < min_parallel_index_scan_size)))
29882986
return 0;
29892987

2990-
if (heap_pages > 0)
2988+
if (heap_pages >= 0)
29912989
{
2990+
int heap_parallel_threshold;
2991+
int heap_parallel_workers = 1;
2992+
29922993
/*
29932994
* Select the number of workers based on the log of the size of
29942995
* the relation. This probably needs to be a good deal more
@@ -3008,8 +3009,11 @@ compute_parallel_worker(RelOptInfo *rel, BlockNumber heap_pages,
30083009
parallel_workers = heap_parallel_workers;
30093010
}
30103011

3011-
if (index_pages > 0)
3012+
if (index_pages >= 0)
30123013
{
3014+
int index_parallel_workers = 1;
3015+
int index_parallel_threshold;
3016+
30133017
/* same calculation as for heap_pages above */
30143018
index_parallel_threshold = Max(min_parallel_index_scan_size, 1);
30153019
while (index_pages >= (BlockNumber) (index_parallel_threshold * 3))

src/backend/optimizer/path/costsize.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,15 +662,22 @@ cost_index(IndexPath *path, PlannerInfo *root, double loop_count,
662662

663663
if (partial_path)
664664
{
665+
/*
666+
* For index only scans compute workers based on number of index pages
667+
* fetched; the number of heap pages we fetch might be so small as
668+
* to effectively rule out parallelism, which we don't want to do.
669+
*/
670+
if (indexonly)
671+
rand_heap_pages = -1;
672+
665673
/*
666674
* Estimate the number of parallel workers required to scan index. Use
667675
* the number of heap pages computed considering heap fetches won't be
668676
* sequential as for parallel scans the pages are accessed in random
669677
* order.
670678
*/
671679
path->path.parallel_workers = compute_parallel_worker(baserel,
672-
(BlockNumber) rand_heap_pages,
673-
(BlockNumber) index_pages);
680+
rand_heap_pages, index_pages);
674681

675682
/*
676683
* Fall out if workers can't be assigned for parallel scan, because in

src/include/optimizer/paths.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ extern RelOptInfo *standard_join_search(PlannerInfo *root, int levels_needed,
5454
List *initial_rels);
5555

5656
extern void generate_gather_paths(PlannerInfo *root, RelOptInfo *rel);
57-
extern int compute_parallel_worker(RelOptInfo *rel, BlockNumber heap_pages,
58-
BlockNumber index_pages);
57+
extern int compute_parallel_worker(RelOptInfo *rel, double heap_pages,
58+
double index_pages);
5959
extern void create_partial_bitmap_paths(PlannerInfo *root, RelOptInfo *rel,
6060
Path *bitmapqual);
6161

0 commit comments

Comments
 (0)