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

Commite092828

Browse files
committed
Teach choose_bitmap_and() to actually be choosy --- that is, try to
make some estimate of which available indexes to AND together, ratherthan blindly taking 'em all. This could probably stand furtherimprovement, but it seems to do OK in simple tests.
1 parent4b89126 commite092828

File tree

1 file changed

+132
-5
lines changed

1 file changed

+132
-5
lines changed

‎src/backend/optimizer/path/indxpath.c

Lines changed: 132 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.176 2005/04/22 21:58:31 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.177 2005/04/23 01:57:34 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -63,6 +63,8 @@ static List *generate_bitmap_or_paths(Query *root, RelOptInfo *rel,
6363
boolisjoininner,
6464
Relidsouter_relids);
6565
staticPath*choose_bitmap_and(Query*root,RelOptInfo*rel,List*paths);
66+
staticintbitmap_path_comparator(constvoid*a,constvoid*b);
67+
staticCostbitmap_and_cost_est(Query*root,RelOptInfo*rel,List*paths);
6668
staticboolmatch_clause_to_indexcol(IndexOptInfo*index,
6769
intindexcol,Oidopclass,
6870
RestrictInfo*rinfo,
@@ -476,15 +478,140 @@ generate_bitmap_or_paths(Query *root, RelOptInfo *rel,
476478
staticPath*
477479
choose_bitmap_and(Query*root,RelOptInfo*rel,List*paths)
478480
{
479-
Assert(paths!=NIL);/* else caller error */
480-
if (list_length(paths)==1)
481-
return (Path*)linitial(paths);/* easy case */
481+
intnpaths=list_length(paths);
482+
Path**patharray;
483+
Costcostsofar;
484+
List*qualsofar;
485+
ListCell*lastcell;
486+
inti;
487+
ListCell*l;
488+
489+
Assert(npaths>0);/* else caller error */
490+
if (npaths==1)
491+
return (Path*)linitial(paths);/* easy case */
492+
482493
/*
483-
* XXX temporary stopgap: always use all available paths
494+
* In theory we should consider every nonempty subset of the given paths.
495+
* In practice that seems like overkill, given the crude nature of the
496+
* estimates, not to mention the possible effects of higher-level AND and
497+
* OR clauses. As a compromise, we sort the paths by selectivity.
498+
* We always take the first, and sequentially add on paths that result
499+
* in a lower estimated cost.
500+
*
501+
* We also make some effort to detect directly redundant input paths,
502+
* as can happen if there are multiple possibly usable indexes. For
503+
* this we look only at plain IndexPath inputs, not at sub-OR clauses.
504+
* And we consider an index redundant if all its index conditions were
505+
* already used by earlier indexes. (We could use pred_test() to have
506+
* a more intelligent, but much more expensive, check --- but in most
507+
* cases simple equality should suffice, since after all the index
508+
* conditions are all coming from the same query clauses.)
484509
*/
510+
511+
/* Convert list to array so we can apply qsort */
512+
patharray= (Path**)palloc(npaths*sizeof(Path*));
513+
i=0;
514+
foreach(l,paths)
515+
{
516+
patharray[i++]= (Path*)lfirst(l);
517+
}
518+
qsort(patharray,npaths,sizeof(Path*),bitmap_path_comparator);
519+
520+
paths=list_make1(patharray[0]);
521+
costsofar=bitmap_and_cost_est(root,rel,paths);
522+
if (IsA(patharray[0],IndexPath))
523+
{
524+
Assert(list_length(((IndexPath*)patharray[0])->indexclauses)==1);
525+
qualsofar= (List*)linitial(((IndexPath*)patharray[0])->indexclauses);
526+
qualsofar=list_copy(qualsofar);
527+
}
528+
else
529+
qualsofar=NIL;
530+
lastcell=list_head(paths);/* for quick deletions */
531+
532+
for (i=1;i<npaths;i++)
533+
{
534+
Path*newpath=patharray[i];
535+
List*newqual=NIL;
536+
Costnewcost;
537+
538+
if (IsA(newpath,IndexPath))
539+
{
540+
Assert(list_length(((IndexPath*)newpath)->indexclauses)==1);
541+
newqual= (List*)linitial(((IndexPath*)newpath)->indexclauses);
542+
if (list_difference(newqual,qualsofar)==NIL)
543+
continue;/* redundant */
544+
}
545+
546+
paths=lappend(paths,newpath);
547+
newcost=bitmap_and_cost_est(root,rel,paths);
548+
if (newcost<costsofar)
549+
{
550+
costsofar=newcost;
551+
if (newqual)
552+
qualsofar=list_concat(qualsofar,list_copy(newqual));
553+
lastcell=lnext(lastcell);
554+
}
555+
else
556+
{
557+
paths=list_delete_cell(paths,lnext(lastcell),lastcell);
558+
}
559+
Assert(lnext(lastcell)==NULL);
560+
}
561+
562+
if (list_length(paths)==1)
563+
return (Path*)linitial(paths);/* no need for AND */
485564
return (Path*)create_bitmap_and_path(root,rel,paths);
486565
}
487566

567+
/* qsort comparator to sort in increasing selectivity order */
568+
staticint
569+
bitmap_path_comparator(constvoid*a,constvoid*b)
570+
{
571+
Path*pa=*(Path*const*)a;
572+
Path*pb=*(Path*const*)b;
573+
Costacost;
574+
Costbcost;
575+
Selectivityaselec;
576+
Selectivitybselec;
577+
578+
cost_bitmap_tree_node(pa,&acost,&aselec);
579+
cost_bitmap_tree_node(pb,&bcost,&bselec);
580+
581+
if (aselec<bselec)
582+
return-1;
583+
if (aselec>bselec)
584+
return1;
585+
/* if identical selectivity, sort by cost */
586+
if (acost<bcost)
587+
return-1;
588+
if (acost>bcost)
589+
return1;
590+
return0;
591+
}
592+
593+
/*
594+
* Estimate the cost of actually executing a BitmapAnd with the given
595+
* inputs.
596+
*/
597+
staticCost
598+
bitmap_and_cost_est(Query*root,RelOptInfo*rel,List*paths)
599+
{
600+
BitmapAndPathapath;
601+
Pathbpath;
602+
603+
/* Set up a dummy BitmapAndPath */
604+
apath.path.type=T_BitmapAndPath;
605+
apath.path.parent=rel;
606+
apath.bitmapquals=paths;
607+
cost_bitmap_and_node(&apath,root);
608+
609+
/* Now we can do cost_bitmap_heap_scan */
610+
cost_bitmap_heap_scan(&bpath,root,rel, (Path*)&apath, false);
611+
612+
returnbpath.total_cost;
613+
}
614+
488615

489616
/****************************************************************************
490617
*---- ROUTINES TO CHECK RESTRICTIONS ----

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp