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

Commit6161766

Browse files
committed
Adjust remove_redundant_join_clauses() so that when it has a choice
of which redundant clause to remove, it removes the more expensive one.In simple scenarios the clauses will be like 'var = var' and there'sno difference, but we are now capable of considering cases where thereare sub-selects in the clauses, and it makes a BIG difference.
1 parentdf79b84 commit6161766

File tree

1 file changed

+60
-29
lines changed

1 file changed

+60
-29
lines changed

‎src/backend/optimizer/util/restrictinfo.c

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.25 2004/01/05 23:39:54 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/restrictinfo.c,v 1.26 2004/02/27 21:48:04 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
1515
#include"postgres.h"
1616

1717
#include"optimizer/clauses.h"
18+
#include"optimizer/cost.h"
1819
#include"optimizer/paths.h"
1920
#include"optimizer/restrictinfo.h"
2021
#include"optimizer/var.h"
@@ -27,7 +28,7 @@ static RestrictInfo *make_restrictinfo_internal(Expr *clause,
2728
staticExpr*make_sub_restrictinfos(Expr*clause,
2829
boolis_pushed_down,
2930
boolvalid_everywhere);
30-
staticbooljoin_clause_is_redundant(Query*root,
31+
staticRestrictInfo*join_clause_is_redundant(Query*root,
3132
RestrictInfo*rinfo,
3233
List*reference_list,
3334
JoinTypejointype);
@@ -317,17 +318,42 @@ remove_redundant_join_clauses(Query *root, List *restrictinfo_list,
317318
{
318319
List*result=NIL;
319320
List*item;
321+
QualCostcost;
322+
323+
/*
324+
* If there are any redundant clauses, we want to eliminate the ones
325+
* that are more expensive in favor of the ones that are less so.
326+
* Run cost_qual_eval() to ensure the eval_cost fields are set up.
327+
*/
328+
cost_qual_eval(&cost,restrictinfo_list);
329+
330+
/*
331+
* We don't have enough knowledge yet to be able to estimate the number
332+
* of times a clause might be evaluated, so it's hard to weight the
333+
* startup and per-tuple costs appropriately. For now just weight 'em
334+
* the same.
335+
*/
336+
#defineCLAUSECOST(r) ((r)->eval_cost.startup + (r)->eval_cost.per_tuple)
320337

321338
foreach(item,restrictinfo_list)
322339
{
323340
RestrictInfo*rinfo= (RestrictInfo*)lfirst(item);
341+
RestrictInfo*prevrinfo;
324342

325-
/* drop it if redundant with any prior clause */
326-
if (join_clause_is_redundant(root,rinfo,result,jointype))
327-
continue;
328-
329-
/* otherwise, add it to result list */
330-
result=lappend(result,rinfo);
343+
/* is it redundant with any prior clause? */
344+
prevrinfo=join_clause_is_redundant(root,rinfo,result,jointype);
345+
if (prevrinfo==NULL)
346+
{
347+
/* no, so add it to result list */
348+
result=lappend(result,rinfo);
349+
}
350+
elseif (CLAUSECOST(rinfo)<CLAUSECOST(prevrinfo))
351+
{
352+
/* keep this one, drop the previous one */
353+
result=lremove(prevrinfo,result);
354+
result=lappend(result,rinfo);
355+
}
356+
/* else, drop this one */
331357
}
332358

333359
returnresult;
@@ -361,7 +387,7 @@ select_nonredundant_join_clauses(Query *root,
361387
RestrictInfo*rinfo= (RestrictInfo*)lfirst(item);
362388

363389
/* drop it if redundant with any reference clause */
364-
if (join_clause_is_redundant(root,rinfo,reference_list,jointype))
390+
if (join_clause_is_redundant(root,rinfo,reference_list,jointype)!=NULL)
365391
continue;
366392

367393
/* otherwise, add it to result list */
@@ -373,7 +399,8 @@ select_nonredundant_join_clauses(Query *root,
373399

374400
/*
375401
* join_clause_is_redundant
376-
*Returns true if rinfo is redundant with any clause in reference_list.
402+
*If rinfo is redundant with any clause in reference_list,
403+
*return one such clause; otherwise return NULL.
377404
*
378405
* This is the guts of both remove_redundant_join_clauses and
379406
* select_nonredundant_join_clauses. See the docs above for motivation.
@@ -398,49 +425,53 @@ select_nonredundant_join_clauses(Query *root,
398425
* then they're not really redundant, because one constrains the
399426
* joined rows after addition of null fill rows, and the other doesn't.
400427
*/
401-
staticbool
428+
staticRestrictInfo*
402429
join_clause_is_redundant(Query*root,
403430
RestrictInfo*rinfo,
404431
List*reference_list,
405432
JoinTypejointype)
406433
{
434+
List*refitem;
435+
407436
/* always consider exact duplicates redundant */
408-
/* XXX would it be sufficient to use ptrMember here? */
409-
if (member(rinfo,reference_list))
410-
return true;
437+
foreach(refitem,reference_list)
438+
{
439+
RestrictInfo*refrinfo= (RestrictInfo*)lfirst(refitem);
440+
441+
if (equal(rinfo,refrinfo))
442+
returnrefrinfo;
443+
}
411444

412445
/* check for redundant merge clauses */
413446
if (rinfo->mergejoinoperator!=InvalidOid)
414447
{
415-
boolredundant= false;
416-
List*refitem;
417-
418448
/* do the cheap test first: is it a "var = const" clause? */
419449
if (bms_is_empty(rinfo->left_relids)||
420450
bms_is_empty(rinfo->right_relids))
421-
returnfalse;/* var = const, so not redundant */
451+
returnNULL;/* var = const, so not redundant */
422452

423453
cache_mergeclause_pathkeys(root,rinfo);
424454

425455
foreach(refitem,reference_list)
426456
{
427457
RestrictInfo*refrinfo= (RestrictInfo*)lfirst(refitem);
428458

429-
if (refrinfo->mergejoinoperator!=InvalidOid&&
430-
rinfo->left_pathkey==refrinfo->left_pathkey&&
431-
rinfo->right_pathkey==refrinfo->right_pathkey&&
432-
(rinfo->is_pushed_down==refrinfo->is_pushed_down||
433-
!IS_OUTER_JOIN(jointype)))
459+
if (refrinfo->mergejoinoperator!=InvalidOid)
434460
{
435-
redundant= true;
436-
break;
461+
cache_mergeclause_pathkeys(root,refrinfo);
462+
463+
if (rinfo->left_pathkey==refrinfo->left_pathkey&&
464+
rinfo->right_pathkey==refrinfo->right_pathkey&&
465+
(rinfo->is_pushed_down==refrinfo->is_pushed_down||
466+
!IS_OUTER_JOIN(jointype)))
467+
{
468+
/* Yup, it's redundant */
469+
returnrefrinfo;
470+
}
437471
}
438472
}
439-
440-
if (redundant)
441-
return true;/* var = var, so redundant */
442473
}
443474

444475
/* otherwise, not redundant */
445-
returnfalse;
476+
returnNULL;
446477
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp