1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-09 06:21:09 +03:00

More optimizer speedups.

This commit is contained in:
Bruce Momjian
1999-02-11 14:59:09 +00:00
parent 129543e22d
commit d244df95db
17 changed files with 192 additions and 131 deletions

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/ordering.c,v 1.11 1999/02/06 17:29:27 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/ordering.c,v 1.12 1999/02/11 14:58:58 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -18,7 +18,7 @@
#include "optimizer/internal.h"
#include "optimizer/ordering.h"
static bool equal_sortops_order(Oid *ordering1, Oid *ordering2);
static bool equal_sortops_order(Oid *ordering1, Oid *ordering2, int *more_sort);
/*
* equal-path-ordering--
@@ -26,14 +26,27 @@ static bool equal_sortops_order(Oid *ordering1, Oid *ordering2);
*
*/
bool
equal_path_ordering(PathOrder *path_ordering1,
PathOrder *path_ordering2)
pathorder_match(PathOrder *path_ordering1,
PathOrder *path_ordering2,
int *more_sort)
{
*more_sort = 0;
if (path_ordering1 == path_ordering2)
return true;
if (!path_ordering2)
{
*more_sort = 1;
return true;
}
if (!path_ordering1 || !path_ordering2)
return false;
if (!path_ordering1)
{
*more_sort = 2;
return true;
}
if (path_ordering1->ordtype == MERGE_ORDER &&
path_ordering2->ordtype == MERGE_ORDER)
@@ -43,19 +56,28 @@ equal_path_ordering(PathOrder *path_ordering1,
else if (path_ordering1->ordtype == SORTOP_ORDER &&
path_ordering2->ordtype == SORTOP_ORDER)
{
return (equal_sortops_order(path_ordering1->ord.sortop,
path_ordering2->ord.sortop));
return equal_sortops_order(path_ordering1->ord.sortop,
path_ordering2->ord.sortop,
more_sort);
}
else if (path_ordering1->ordtype == MERGE_ORDER &&
path_ordering2->ordtype == SORTOP_ORDER)
{
return (path_ordering2->ord.sortop &&
(path_ordering1->ord.merge->left_operator == path_ordering2->ord.sortop[0]));
if (!path_ordering2->ord.sortop)
{
*more_sort = 1;
return true;
}
return path_ordering1->ord.merge->left_operator == path_ordering2->ord.sortop[0];
}
else
{
return (path_ordering1->ord.sortop &&
(path_ordering1->ord.sortop[0] == path_ordering2->ord.merge->left_operator));
if (!path_ordering1->ord.sortop)
{
*more_sort = 2;
return true;
}
return path_ordering1->ord.sortop[0] == path_ordering2->ord.merge->left_operator;
}
}
@@ -105,13 +127,27 @@ equal_merge_ordering(MergeOrder *merge_ordering1,
* Returns true iff the sort operators are in the same order.
*/
static bool
equal_sortops_order(Oid *ordering1, Oid *ordering2)
equal_sortops_order(Oid *ordering1, Oid *ordering2, int *more_sort)
{
int i = 0;
if (ordering1 == NULL || ordering2 == NULL)
return ordering1 == ordering2;
*more_sort = 0;
if (ordering1 == ordering2)
return true;
if (!ordering2)
{
*more_sort = 1;
return true;
}
if (!ordering1)
{
*more_sort = 2;
return true;
}
while (ordering1[i] != 0 && ordering2[i] != 0)
{
if (ordering1[i] != ordering2[i])
@@ -119,5 +155,17 @@ equal_sortops_order(Oid *ordering1, Oid *ordering2)
i++;
}
if (ordering1[i] != 0 && ordering2[i] == 0)
{
*more_sort = 1;
return true;
}
if (ordering1[i] == 0 && ordering2[i] != 0)
{
*more_sort = 2;
return true;
}
return ordering1[i] == 0 && ordering2[i] == 0;
}

View File

@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.25 1999/02/11 05:29:08 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.26 1999/02/11 14:59:02 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -158,7 +158,8 @@ better_path(Path *new_path, List *unique_paths, bool *is_new)
Path *path = (Path *) NULL;
List *temp = NIL;
int longer_key;
int more_sort;
foreach(temp, unique_paths)
{
path = (Path *) lfirst(temp);
@@ -176,18 +177,18 @@ better_path(Path *new_path, List *unique_paths, bool *is_new)
length(lfirst(path->pathkeys)) < length(lfirst(new_path->pathkeys)))
sleep(0); /* set breakpoint here */
}
if (!equal_path_ordering(new_path->path_order, path->path_order))
if (!pathorder_match(new_path->pathorder, path->pathorder, &more_sort))
{
printf("oldord\n");
pprint(path->path_order);
pprint(path->pathorder);
printf("neword\n");
pprint(new_path->path_order);
pprint(new_path->pathorder);
}
#endif
if (pathkeys_match(new_path->pathkeys, path->pathkeys, &longer_key))
{
if (equal_path_ordering(new_path->path_order, path->path_order))
if (pathorder_match(new_path->pathorder, path->pathorder, &more_sort))
{
/*
* Replace pathkeys that match exactly, (1,2), (1,2).
@@ -196,18 +197,28 @@ better_path(Path *new_path, List *unique_paths, bool *is_new)
* path if it is not more expensive.
*/
/* same keys, and new is cheaper, use it */
if ((longer_key == 0 && new_path->path_cost < path->path_cost) ||
/* new is longer, and cheaper, use it */
(longer_key == 1 && new_path->path_cost <= path->path_cost))
/* same keys, and new is cheaper, use it */
if ((longer_key == 0 && more_sort == 0 &&
new_path->path_cost < path->path_cost) ||
/* new is better, and cheaper, use it */
((longer_key == 1 && more_sort != 2) ||
(longer_key != 2 && more_sort == 1)) &&
new_path->path_cost <= path->path_cost)
{
*is_new = false;
return new_path;
}
/* same keys, new is more expensive, stop */
else if ((longer_key == 0 && new_path->path_cost >= path->path_cost) ||
/* old is longer, and less expensive, stop */
(longer_key == 2 && new_path->path_cost >= path->path_cost))
/* same keys, new is more expensive, stop */
else if
((longer_key == 0 && more_sort == 0 &&
new_path->path_cost >= path->path_cost) ||
/* old is better, and less expensive, stop */
((longer_key == 2 && more_sort != 1) ||
(longer_key != 1 && more_sort == 2)) &&
new_path->path_cost >= path->path_cost)
{
*is_new = false;
return NULL;
@@ -242,9 +253,9 @@ create_seqscan_path(RelOptInfo *rel)
pathnode->pathtype = T_SeqScan;
pathnode->parent = rel;
pathnode->path_cost = 0.0;
pathnode->path_order = makeNode(PathOrder);
pathnode->path_order->ordtype = SORTOP_ORDER;
pathnode->path_order->ord.sortop = NULL;
pathnode->pathorder = makeNode(PathOrder);
pathnode->pathorder->ordtype = SORTOP_ORDER;
pathnode->pathorder->ord.sortop = NULL;
pathnode->pathkeys = NIL;
/*
@@ -292,9 +303,9 @@ create_index_path(Query *root,
pathnode->path.pathtype = T_IndexScan;
pathnode->path.parent = rel;
pathnode->path.path_order = makeNode(PathOrder);
pathnode->path.path_order->ordtype = SORTOP_ORDER;
pathnode->path.path_order->ord.sortop = index->ordering;
pathnode->path.pathorder = makeNode(PathOrder);
pathnode->path.pathorder->ordtype = SORTOP_ORDER;
pathnode->path.pathorder->ord.sortop = index->ordering;
pathnode->indexid = index->relids;
pathnode->indexkeys = index->indexkeys;
@@ -311,7 +322,7 @@ create_index_path(Query *root,
* The index must have an ordering for the path to have (ordering)
* keys, and vice versa.
*/
if (pathnode->path.path_order->ord.sortop)
if (pathnode->path.pathorder->ord.sortop)
{
pathnode->path.pathkeys = collect_index_pathkeys(index->indexkeys,
rel->targetlist);
@@ -323,7 +334,7 @@ create_index_path(Query *root,
* if no index keys were found, we can't order the path).
*/
if (pathnode->path.pathkeys == NULL)
pathnode->path.path_order->ord.sortop = NULL;
pathnode->path.pathorder->ord.sortop = NULL;
}
else
pathnode->path.pathkeys = NULL;
@@ -449,20 +460,20 @@ create_nestloop_path(RelOptInfo *joinrel,
pathnode->path.joinid = NIL;
pathnode->path.outerjoincost = (Cost) 0.0;
pathnode->path.loc_restrictinfo = NIL;
pathnode->path.path_order = makeNode(PathOrder);
pathnode->path.pathorder = makeNode(PathOrder);
if (pathkeys)
{
pathnode->path.path_order->ordtype = outer_path->path_order->ordtype;
if (outer_path->path_order->ordtype == SORTOP_ORDER)
pathnode->path.path_order->ord.sortop = outer_path->path_order->ord.sortop;
pathnode->path.pathorder->ordtype = outer_path->pathorder->ordtype;
if (outer_path->pathorder->ordtype == SORTOP_ORDER)
pathnode->path.pathorder->ord.sortop = outer_path->pathorder->ord.sortop;
else
pathnode->path.path_order->ord.merge = outer_path->path_order->ord.merge;
pathnode->path.pathorder->ord.merge = outer_path->pathorder->ord.merge;
}
else
{
pathnode->path.path_order->ordtype = SORTOP_ORDER;
pathnode->path.path_order->ord.sortop = NULL;
pathnode->path.pathorder->ordtype = SORTOP_ORDER;
pathnode->path.pathorder->ord.sortop = NULL;
}
pathnode->path.path_cost = cost_nestloop(outer_path->path_cost,
@@ -521,9 +532,9 @@ create_mergejoin_path(RelOptInfo *joinrel,
pathnode->jpath.innerjoinpath = inner_path;
pathnode->jpath.pathinfo = joinrel->restrictinfo;
pathnode->jpath.path.pathkeys = pathkeys;
pathnode->jpath.path.path_order = makeNode(PathOrder);
pathnode->jpath.path.path_order->ordtype = MERGE_ORDER;
pathnode->jpath.path.path_order->ord.merge = order;
pathnode->jpath.path.pathorder = makeNode(PathOrder);
pathnode->jpath.path.pathorder->ordtype = MERGE_ORDER;
pathnode->jpath.path.pathorder->ord.merge = order;
pathnode->path_mergeclauses = mergeclauses;
pathnode->jpath.path.loc_restrictinfo = NIL;
pathnode->outersortkeys = outersortkeys;
@@ -587,9 +598,9 @@ create_hashjoin_path(RelOptInfo *joinrel,
pathnode->jpath.pathinfo = joinrel->restrictinfo;
pathnode->jpath.path.loc_restrictinfo = NIL;
pathnode->jpath.path.pathkeys = pathkeys;
pathnode->jpath.path.path_order = makeNode(PathOrder);
pathnode->jpath.path.path_order->ordtype = SORTOP_ORDER;
pathnode->jpath.path.path_order->ord.sortop = NULL;
pathnode->jpath.path.pathorder = makeNode(PathOrder);
pathnode->jpath.path.pathorder->ordtype = SORTOP_ORDER;
pathnode->jpath.path.pathorder->ord.sortop = NULL;
pathnode->jpath.path.outerjoincost = (Cost) 0.0;
pathnode->jpath.path.joinid = (Relid) NULL;
/* pathnode->hashjoinoperator = operator; */