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

Commit1fcd4b7

Browse files
committed
While determining the filter clauses for an index scan (either plain
or bitmap), use pred_test to be a little smarter about cases where afilter clause is logically unnecessary. This may be overkill for theplain indexscan case, but it's definitely useful for OR'd bitmap scans.
1 parent79a1b00 commit1fcd4b7

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

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

Lines changed: 10 additions & 4 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.178 2005/04/2501:30:13 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.179 2005/04/2503:58:29 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -500,8 +500,14 @@ choose_bitmap_and(Query *root, RelOptInfo *rel, List *paths)
500500
* And we consider an index redundant if all its index conditions were
501501
* already used by earlier indexes. (We could use pred_test() to have
502502
* a more intelligent, but much more expensive, check --- but in most
503-
* cases simple equality should suffice, since after all the index
504-
* conditions are all coming from the same query clauses.)
503+
* cases simple pointer equality should suffice, since after all the
504+
* index conditions are all coming from the same RestrictInfo lists.)
505+
*
506+
* XXX is there any risk of throwing away a useful partial index here
507+
* because we don't explicitly look at indpred? At least in simple
508+
* cases, the partial index will sort before competing non-partial
509+
* indexes and so it makes the right choice, but perhaps we need to
510+
* work harder.
505511
*/
506512

507513
/* Convert list to array so we can apply qsort */
@@ -530,7 +536,7 @@ choose_bitmap_and(Query *root, RelOptInfo *rel, List *paths)
530536
if (IsA(newpath,IndexPath))
531537
{
532538
newqual= ((IndexPath*)newpath)->indexclauses;
533-
if (list_difference(newqual,qualsofar)==NIL)
539+
if (list_difference_ptr(newqual,qualsofar)==NIL)
534540
continue;/* redundant */
535541
}
536542

‎src/backend/optimizer/plan/createplan.c

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.186 2005/04/2502:14:47 tgl Exp $
13+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.187 2005/04/2503:58:30 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -720,6 +720,7 @@ create_indexscan_plan(Query *root,
720720
List*nonlossy_indexquals;
721721
List*indexstrategy;
722722
List*indexsubtype;
723+
ListCell*l;
723724
IndexScan*scan_plan;
724725

725726
/* it should be a base rel... */
@@ -768,13 +769,31 @@ create_indexscan_plan(Query *root,
768769
* checked (either by the index itself, or by nodeIndexscan.c), but if
769770
* there are any "special" operators involved then they must be included
770771
* in qpqual. Also, any lossy index operators must be rechecked in
771-
* the qpqual. The upshot is thatqpquals must contain scan_clauses
772+
* the qpqual. The upshot is thatqpqual must contain scan_clauses
772773
* minus whatever appears in nonlossy_indexquals.
774+
*
775+
* In normal cases simple pointer equality checks will be enough to
776+
* spot duplicate RestrictInfos, so we try that first. In some situations
777+
* (particularly with OR'd index conditions) we may have scan_clauses
778+
* that are not equal to, but are logically implied by, the index quals;
779+
* so we also try a pred_test() check to see if we can discard quals
780+
* that way.
781+
*
782+
* While at it, we strip off the RestrictInfos to produce a list of
783+
* plain expressions.
773784
*/
774-
qpqual=list_difference_ptr(scan_clauses,nonlossy_indexquals);
785+
qpqual=NIL;
786+
foreach(l,scan_clauses)
787+
{
788+
RestrictInfo*rinfo= (RestrictInfo*)lfirst(l);
775789

776-
/* Reduce RestrictInfo list to bare expressions */
777-
qpqual=get_actual_clauses(qpqual);
790+
Assert(IsA(rinfo,RestrictInfo));
791+
if (list_member_ptr(nonlossy_indexquals,rinfo))
792+
continue;
793+
if (pred_test(list_make1(rinfo->clause),nonlossy_indexquals))
794+
continue;
795+
qpqual=lappend(qpqual,rinfo->clause);
796+
}
778797

779798
/* Sort clauses into best execution order */
780799
qpqual=order_qual_clauses(root,qpqual);
@@ -813,6 +832,7 @@ create_bitmap_scan_plan(Query *root,
813832
List*bitmapqualorig;
814833
List*indexquals;
815834
List*qpqual;
835+
ListCell*l;
816836
BitmapHeapScan*scan_plan;
817837

818838
/* it should be a base rel... */
@@ -848,13 +868,23 @@ create_bitmap_scan_plan(Query *root,
848868
* must be added to qpqual. The upshot is that qpquals must contain
849869
* scan_clauses minus whatever appears in indexquals.
850870
*
851-
*NOTE: when there are OR clauses in indexquals, the simple equality
852-
*check used by list_difference will only detect matches in case of
853-
*chance equality of the OR subclause ordering. This is probably all
854-
*right for now because that order will match what's in scan_clauses
855-
*... but perhapsweneed more smarts here.
871+
*In normal cases simple equal() checks will be enough to spot duplicate
872+
*clauses, so we try that first. In some situations (particularly with
873+
*OR'd index conditions) we may have scan_clauses that are not equal to,
874+
*but are logically implied by, the index quals; so we also try a
875+
*pred_test() check to see ifwecan discard quals that way.
856876
*/
857-
qpqual=list_difference(scan_clauses,indexquals);
877+
qpqual=NIL;
878+
foreach(l,scan_clauses)
879+
{
880+
Node*clause= (Node*)lfirst(l);
881+
882+
if (list_member(indexquals,clause))
883+
continue;
884+
if (pred_test(list_make1(clause),indexquals))
885+
continue;
886+
qpqual=lappend(qpqual,clause);
887+
}
858888

859889
/* Sort clauses into best execution order */
860890
qpqual=order_qual_clauses(root,qpqual);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp