Skip to content

Commit e5f5238

Browse files
committed
Consider ndistinct on the first column in cost_sort().
Task: 9578. Tags: optimized_group_by.
1 parent 9c3dab9 commit e5f5238

File tree

3 files changed

+52
-25
lines changed

3 files changed

+52
-25
lines changed

src/backend/optimizer/path/costsize.c

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ static double page_size(double tuples, int width);
194194
static double get_parallel_divisor(Path *path);
195195
static EquivalenceMember *identify_sort_ecmember(PlannerInfo *root,
196196
PathKey *key);
197+
static double sort_comparisons_factor(PlannerInfo *root, List *pathkeys,
198+
double ntuples);
197199

198200

199201
/*
@@ -2113,8 +2115,7 @@ cost_sort(Path *path, PlannerInfo *root,
21132115
{
21142116
Cost startup_cost;
21152117
Cost run_cost;
2116-
double cmpMultiplier =
2117-
(pathkeys == NIL) ? 2.0 : list_length(pathkeys) + 1.0;
2118+
double cmpMultiplier = sort_comparisons_factor(root, pathkeys, tuples);
21182119

21192120
cost_tuplesort(&startup_cost, &run_cost,
21202121
tuples, width, cmpMultiplier,
@@ -6560,4 +6561,32 @@ identify_sort_ecmember(PlannerInfo *root, PathKey *key)
65606561

65616562
Assert(candidate != NULL);
65626563
return candidate;
6563-
}
6564+
}
6565+
6566+
static double
6567+
sort_comparisons_factor(PlannerInfo *root, List *pathkeys, double ntuples)
6568+
{
6569+
int n = list_length(pathkeys);
6570+
double cmpMultiplier = (n == 0) ? 2.0 : n + 1;
6571+
6572+
if (root != NULL && ntuples > 1 && n > 1)
6573+
{
6574+
PathKey *key = linitial_node(PathKey, pathkeys);
6575+
EquivalenceMember *em = identify_sort_ecmember(root, key);
6576+
6577+
Assert(em->em_ndistinct >= 0);
6578+
6579+
if (em->em_ndistinct == 0.)
6580+
/*
6581+
* Optimiser doesn't have an info on ndistinct value, return
6582+
* extreme case
6583+
*/
6584+
return cmpMultiplier;
6585+
6586+
if (ntuples >= em->em_ndistinct)
6587+
cmpMultiplier =
6588+
2.0 + ((ntuples - em->em_ndistinct) / (ntuples - 1)) * (n - 1);
6589+
}
6590+
6591+
return cmpMultiplier;
6592+
}

src/test/regress/expected/aggregates.out

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,19 +2842,18 @@ SELECT count(*)
28422842
QUERY PLAN
28432843
-------------------------------------------------------------------------------
28442844
GroupAggregate
2845-
Group Key: t1.z, t1.w, t1.x, t1.y
2846-
-> Incremental Sort
2847-
Sort Key: t1.z, t1.w, t1.x, t1.y
2848-
Presorted Key: t1.z, t1.w, t1.x
2845+
Group Key: t1.x, t1.y, t1.z, t1.w
2846+
-> Sort
2847+
Sort Key: t1.x, t1.y, t1.z, t1.w
28492848
-> Merge Join
2850-
Merge Cond: ((t1.z = t2.z) AND (t1.w = t2.w) AND (t1.x = t2.x))
2849+
Merge Cond: ((t1.w = t2.w) AND (t1.z = t2.z) AND (t1.x = t2.x))
28512850
-> Sort
2852-
Sort Key: t1.z, t1.w, t1.x
2851+
Sort Key: t1.w, t1.z, t1.x
28532852
-> Index Scan using btg_x_y_idx on btg t1
28542853
-> Sort
2855-
Sort Key: t2.z, t2.w, t2.x
2854+
Sort Key: t2.w, t2.z, t2.x
28562855
-> Index Scan using btg_x_y_idx on btg t2
2857-
(13 rows)
2856+
(12 rows)
28582857

28592858
RESET enable_nestloop;
28602859
RESET enable_hashjoin;
@@ -2878,12 +2877,11 @@ SELECT count(*) FROM btg GROUP BY w, x, y, z ORDER BY x*x, z;
28782877
Sort
28792878
Sort Key: ((x * x)), z
28802879
-> GroupAggregate
2881-
Group Key: x, y, w, z
2882-
-> Incremental Sort
2883-
Sort Key: x, y, w, z
2884-
Presorted Key: x, y
2880+
Group Key: w, x, y, z
2881+
-> Sort
2882+
Sort Key: w, x, y, z
28852883
-> Index Scan using btg_x_y_idx on btg
2886-
(8 rows)
2884+
(7 rows)
28872885

28882886
-- Test the case where the number of incoming subtree path keys is more than
28892887
-- the number of grouping keys.

src/test/regress/expected/partition_join.out

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -615,39 +615,39 @@ SELECT a, b FROM prt1 FULL JOIN prt2 p2(b,a,c) USING(a,b)
615615
-> Sort
616616
Sort Key: (COALESCE(prt1.a, p2.a)), (COALESCE(prt1.b, p2.b))
617617
-> Merge Full Join
618-
Merge Cond: ((prt1.a = p2.a) AND (prt1.b = p2.b))
618+
Merge Cond: ((prt1.b = p2.b) AND (prt1.a = p2.a))
619619
Filter: ((COALESCE(prt1.a, p2.a) >= 490) AND (COALESCE(prt1.a, p2.a) <= 510))
620620
-> Sort
621-
Sort Key: prt1.a, prt1.b
621+
Sort Key: prt1.b, prt1.a
622622
-> Seq Scan on prt1_p1 prt1
623623
-> Sort
624-
Sort Key: p2.a, p2.b
624+
Sort Key: p2.b, p2.a
625625
-> Seq Scan on prt2_p1 p2
626626
-> Group
627627
Group Key: (COALESCE(prt1_1.a, p2_1.a)), (COALESCE(prt1_1.b, p2_1.b))
628628
-> Sort
629629
Sort Key: (COALESCE(prt1_1.a, p2_1.a)), (COALESCE(prt1_1.b, p2_1.b))
630630
-> Merge Full Join
631-
Merge Cond: ((prt1_1.a = p2_1.a) AND (prt1_1.b = p2_1.b))
631+
Merge Cond: ((prt1_1.b = p2_1.b) AND (prt1_1.a = p2_1.a))
632632
Filter: ((COALESCE(prt1_1.a, p2_1.a) >= 490) AND (COALESCE(prt1_1.a, p2_1.a) <= 510))
633633
-> Sort
634-
Sort Key: prt1_1.a, prt1_1.b
634+
Sort Key: prt1_1.b, prt1_1.a
635635
-> Seq Scan on prt1_p2 prt1_1
636636
-> Sort
637-
Sort Key: p2_1.a, p2_1.b
637+
Sort Key: p2_1.b, p2_1.a
638638
-> Seq Scan on prt2_p2 p2_1
639639
-> Group
640640
Group Key: (COALESCE(prt1_2.a, p2_2.a)), (COALESCE(prt1_2.b, p2_2.b))
641641
-> Sort
642642
Sort Key: (COALESCE(prt1_2.a, p2_2.a)), (COALESCE(prt1_2.b, p2_2.b))
643643
-> Merge Full Join
644-
Merge Cond: ((prt1_2.a = p2_2.a) AND (prt1_2.b = p2_2.b))
644+
Merge Cond: ((prt1_2.b = p2_2.b) AND (prt1_2.a = p2_2.a))
645645
Filter: ((COALESCE(prt1_2.a, p2_2.a) >= 490) AND (COALESCE(prt1_2.a, p2_2.a) <= 510))
646646
-> Sort
647-
Sort Key: prt1_2.a, prt1_2.b
647+
Sort Key: prt1_2.b, prt1_2.a
648648
-> Seq Scan on prt1_p3 prt1_2
649649
-> Sort
650-
Sort Key: p2_2.a, p2_2.b
650+
Sort Key: p2_2.b, p2_2.a
651651
-> Seq Scan on prt2_p3 p2_2
652652
(43 rows)
653653

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