Skip to content

Commit 91224ee

Browse files
committed
Partial sort
1 parent 8eea52e commit 91224ee

File tree

4 files changed

+85
-15
lines changed

4 files changed

+85
-15
lines changed

src/backend/optimizer/path/pathkeys.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,40 @@ get_cheapest_fractional_path_for_pathkeys(List *paths,
430430
return matched_path;
431431
}
432432

433+
Path *
434+
get_cheapest_partial_path_for_pathkeys(List *paths,
435+
List *pathkeys,
436+
Relids required_outer,
437+
double fraction)
438+
{
439+
Path *matched_path = NULL;
440+
ListCell *l;
441+
int best_prefix_len = 0;
442+
foreach(l, paths)
443+
{
444+
Path *path = (Path *) lfirst(l);
445+
int prefix_len = pathkeys_get_prefix(pathkeys, path->pathkeys);
446+
if (prefix_len < best_prefix_len || path->pathtype != T_IndexOnlyScan) {
447+
continue;
448+
}
449+
/*
450+
* Since cost comparison is a lot cheaper than pathkey comparison, do
451+
* that first. (XXX is that still true?)
452+
*/
453+
if (matched_path != NULL &&
454+
compare_fractional_path_costs(matched_path, path, fraction) <= 0)
455+
continue;
456+
457+
if (prefix_len != 0
458+
&& bms_is_subset(PATH_REQ_OUTER(path), required_outer))
459+
{
460+
matched_path = path;
461+
best_prefix_len = prefix_len;
462+
}
463+
}
464+
return matched_path;
465+
}
466+
433467
/****************************************************************************
434468
* NEW PATHKEY FORMATION
435469
****************************************************************************/
@@ -1483,13 +1517,17 @@ pathkeys_useful_for_ordering(PlannerInfo *root, List *pathkeys)
14831517
if (pathkeys == NIL)
14841518
return 0; /* unordered path */
14851519

1520+
#if 0
14861521
if (pathkeys_contained_in(root->query_pathkeys, pathkeys))
14871522
{
14881523
/* It's useful ... or at least the first N keys are */
14891524
return list_length(root->query_pathkeys);
14901525
}
14911526

14921527
return 0; /* path ordering not useful */
1528+
#else
1529+
return pathkeys_get_prefix(root->query_pathkeys, pathkeys);
1530+
#endif
14931531
}
14941532

14951533
/*

src/backend/optimizer/plan/createplan.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4049,17 +4049,6 @@ make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
40494049
0.0,
40504050
work_mem,
40514051
limit_tuples);
4052-
if (lefttree->type == T_IndexOnlyScan && root->simple_rel_array_size == 2)
4053-
{
4054-
RelOptInfo* relinfo = root->simple_rel_array[1];
4055-
IndexOptInfo* indexinfo = linitial(root->simple_rel_array[1]->indexlist);
4056-
IndexOnlyScan* indexscan = (IndexOnlyScan*)lefttree;
4057-
List *index_pathkeys = build_index_pathkeys(root, indexinfo, indexscan->indexorderdir);
4058-
int prefix_len = pathkeys_get_prefix(root->query_pathkeys, index_pathkeys);
4059-
sort_path.total_cost -= sort_path.startup_cost;
4060-
sort_path.startup_cost /= (prefix_len+1);
4061-
sort_path.total_cost += sort_path.startup_cost;
4062-
}
40634052
plan->startup_cost = sort_path.startup_cost;
40644053
plan->total_cost = sort_path.total_cost;
40654054
plan->targetlist = lefttree->targetlist;

src/backend/optimizer/plan/planner.c

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,6 +1334,10 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
13341334
double dNumGroups = 0;
13351335
bool use_hashed_distinct = false;
13361336
bool tested_hashed_distinct = false;
1337+
Path *cheapest_path;
1338+
Path *sorted_path = NULL;
1339+
Path *partial_sorted_path = NULL;
1340+
Path *best_path = NULL;
13371341

13381342
/* Tweak caller-supplied tuple_fraction if have LIMIT/OFFSET */
13391343
if (parse->limitCount || parse->limitOffset)
@@ -1434,9 +1438,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
14341438
List *rollup_groupclauses = NIL;
14351439
standard_qp_extra qp_extra;
14361440
RelOptInfo *final_rel;
1437-
Path *cheapest_path;
1438-
Path *sorted_path;
1439-
Path *best_path;
14401441

14411442
MemSet(&agg_costs, 0, sizeof(AggClauseCosts));
14421443

@@ -1764,7 +1765,14 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
17641765
root->query_pathkeys,
17651766
NULL,
17661767
tuple_fraction);
1767-
1768+
if (sorted_path == NULL)
1769+
{
1770+
partial_sorted_path =
1771+
get_cheapest_partial_path_for_pathkeys(final_rel->pathlist,
1772+
root->query_pathkeys,
1773+
NULL,
1774+
tuple_fraction);
1775+
}
17681776
/* Don't consider same path in both guises; just wastes effort */
17691777
if (sorted_path == cheapest_path)
17701778
sorted_path = NULL;
@@ -1803,7 +1811,32 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
18031811
/* Presorted path is a loser */
18041812
sorted_path = NULL;
18051813
}
1814+
} else if (partial_sorted_path != NULL) {
1815+
Path sort_path;
1816+
Path partial_sort_path;
1817+
1818+
cost_sort(&sort_path, root, root->query_pathkeys,
1819+
cheapest_path->total_cost,
1820+
path_rows, path_width,
1821+
0.0, work_mem, root->limit_tuples);
1822+
1823+
cost_sort(&partial_sort_path, root, root->query_pathkeys,
1824+
partial_sorted_path->total_cost,
1825+
path_rows, path_width,
1826+
0.0, work_mem, root->limit_tuples);
1827+
1828+
partial_sort_path.total_cost -= partial_sort_path.startup_cost;
1829+
partial_sort_path.startup_cost /= partial_sorted_path->pathkeys->length+1;
1830+
partial_sort_path.total_cost += partial_sort_path.startup_cost;
1831+
1832+
1833+
if (compare_fractional_path_costs(&sort_path, &partial_sort_path,
1834+
tuple_fraction) > 0)
1835+
{
1836+
cheapest_path = partial_sorted_path;
1837+
}
18061838
}
1839+
18071840

18081841
/*
18091842
* Consider whether we want to use hashing instead of sorting.
@@ -2370,6 +2403,12 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
23702403
result_plan,
23712404
root->sort_pathkeys,
23722405
limit_tuples);
2406+
if (partial_sorted_path && best_path == partial_sorted_path)
2407+
{
2408+
result_plan->total_cost -= result_plan->startup_cost;
2409+
result_plan->startup_cost /= partial_sorted_path->pathkeys->length+1;
2410+
result_plan->total_cost += result_plan->startup_cost;
2411+
}
23732412
current_pathkeys = root->sort_pathkeys;
23742413
}
23752414
}

src/include/optimizer/paths.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,10 @@ extern Path *get_cheapest_fractional_path_for_pathkeys(List *paths,
175175
List *pathkeys,
176176
Relids required_outer,
177177
double fraction);
178+
extern Path *get_cheapest_partial_path_for_pathkeys(List *paths,
179+
List *pathkeys,
180+
Relids required_outer,
181+
double fraction);
178182
extern List *build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index,
179183
ScanDirection scandir);
180184
extern List *build_expression_pathkey(PlannerInfo *root, Expr *expr,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy