8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.111 2007/01/20 20:45:39 tgl Exp $
11
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/joinpath.c,v 1.112 2007/05/22 01:40:33 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -286,10 +286,11 @@ sort_inner_and_outer(PlannerInfo *root,
286
286
* only outer paths that are already ordered well enough for merging).
287
287
*
288
288
* We always generate a nestloop path for each available outer path.
289
- * In fact we may generate as many as four : one on the cheapest-total-cost
289
+ * In fact we may generate as many as five : one on the cheapest-total-cost
290
290
* inner path, one on the same with materialization, one on the
291
- * cheapest-startup-cost inner path (if different),
292
- * and one on the best inner-indexscan path (if any).
291
+ * cheapest-startup-cost inner path (if different), one on the
292
+ * cheapest-total inner-indexscan path (if any), and one on the
293
+ * cheapest-startup inner-indexscan path (if different).
293
294
*
294
295
* We also consider mergejoins if mergejoin clauses are available. We have
295
296
* two ways to generate the inner path for a mergejoin: sort the cheapest
@@ -325,7 +326,8 @@ match_unsorted_outer(PlannerInfo *root,
325
326
Path * inner_cheapest_startup = innerrel -> cheapest_startup_path ;
326
327
Path * inner_cheapest_total = innerrel -> cheapest_total_path ;
327
328
Path * matpath = NULL ;
328
- Path * bestinnerjoin = NULL ;
329
+ Path * index_cheapest_startup = NULL ;
330
+ Path * index_cheapest_total = NULL ;
329
331
ListCell * l ;
330
332
331
333
/*
@@ -383,17 +385,20 @@ match_unsorted_outer(PlannerInfo *root,
383
385
create_material_path (innerrel , inner_cheapest_total );
384
386
385
387
/*
386
- * Get the best innerjoin indexpath (if any) for this outer rel. It's
387
- * the same for all outer paths.
388
+ * Get the best innerjoin indexpaths (if any) for this outer rel.
389
+ * They're the same for all outer paths.
388
390
*/
389
391
if (innerrel -> reloptkind != RELOPT_JOINREL )
390
392
{
391
393
if (IsA (inner_cheapest_total , AppendPath ))
392
- bestinnerjoin = best_appendrel_indexscan (root , innerrel ,
393
- outerrel , jointype );
394
+ index_cheapest_total = best_appendrel_indexscan (root ,
395
+ innerrel ,
396
+ outerrel ,
397
+ jointype );
394
398
else if (innerrel -> rtekind == RTE_RELATION )
395
- bestinnerjoin = best_inner_indexscan (root , innerrel ,
396
- outerrel , jointype );
399
+ best_inner_indexscan (root , innerrel , outerrel , jointype ,
400
+ & index_cheapest_startup ,
401
+ & index_cheapest_total );
397
402
}
398
403
}
399
404
@@ -435,8 +440,8 @@ match_unsorted_outer(PlannerInfo *root,
435
440
* Always consider a nestloop join with this outer and
436
441
* cheapest-total-cost inner. When appropriate, also consider
437
442
* using the materialized form of the cheapest inner, the
438
- * cheapest-startup-cost inner path, and the best innerjoin
439
- * indexpath .
443
+ * cheapest-startup-cost inner path, and the cheapest innerjoin
444
+ * indexpaths .
440
445
*/
441
446
add_path (joinrel , (Path * )
442
447
create_nestloop_path (root ,
@@ -464,13 +469,23 @@ match_unsorted_outer(PlannerInfo *root,
464
469
inner_cheapest_startup ,
465
470
restrictlist ,
466
471
merge_pathkeys ));
467
- if (bestinnerjoin != NULL )
472
+ if (index_cheapest_total != NULL )
468
473
add_path (joinrel , (Path * )
469
474
create_nestloop_path (root ,
470
475
joinrel ,
471
476
jointype ,
472
477
outerpath ,
473
- bestinnerjoin ,
478
+ index_cheapest_total ,
479
+ restrictlist ,
480
+ merge_pathkeys ));
481
+ if (index_cheapest_startup != NULL &&
482
+ index_cheapest_startup != index_cheapest_total )
483
+ add_path (joinrel , (Path * )
484
+ create_nestloop_path (root ,
485
+ joinrel ,
486
+ jointype ,
487
+ outerpath ,
488
+ index_cheapest_startup ,
474
489
restrictlist ,
475
490
merge_pathkeys ));
476
491
}
@@ -789,6 +804,9 @@ hash_inner_and_outer(PlannerInfo *root,
789
804
* with the given append relation on the inside and the given outer_rel
790
805
* outside. Returns an AppendPath comprising the best inner scans, or
791
806
* NULL if there are no possible inner indexscans.
807
+ *
808
+ * Note that we currently consider only cheapest-total-cost. It's not
809
+ * very clear what cheapest-startup-cost might mean for an AppendPath.
792
810
*/
793
811
static Path *
794
812
best_appendrel_indexscan (PlannerInfo * root , RelOptInfo * rel ,
@@ -804,7 +822,8 @@ best_appendrel_indexscan(PlannerInfo *root, RelOptInfo *rel,
804
822
AppendRelInfo * appinfo = (AppendRelInfo * ) lfirst (l );
805
823
int childRTindex ;
806
824
RelOptInfo * childrel ;
807
- Path * bestinnerjoin ;
825
+ Path * index_cheapest_startup ;
826
+ Path * index_cheapest_total ;
808
827
809
828
/* append_rel_list contains all append rels; ignore others */
810
829
if (appinfo -> parent_relid != parentRTindex )
@@ -824,23 +843,23 @@ best_appendrel_indexscan(PlannerInfo *root, RelOptInfo *rel,
824
843
continue ; /* OK, we can ignore it */
825
844
826
845
/*
827
- * Get the best innerjoin indexpath (if any) for this child rel.
846
+ * Get the best innerjoin indexpaths (if any) for this child rel.
828
847
*/
829
- bestinnerjoin = best_inner_indexscan (root , childrel ,
830
- outer_rel , jointype );
848
+ best_inner_indexscan (root , childrel , outer_rel , jointype ,
849
+ & index_cheapest_startup , & index_cheapest_total );
831
850
832
851
/*
833
852
* If no luck on an indexpath for this rel, we'll still consider an
834
853
* Append substituting the cheapest-total inner path. However we must
835
854
* find at least one indexpath, else there's not going to be any
836
855
* improvement over the base path for the appendrel.
837
856
*/
838
- if (bestinnerjoin )
857
+ if (index_cheapest_total )
839
858
found_indexscan = true;
840
859
else
841
- bestinnerjoin = childrel -> cheapest_total_path ;
860
+ index_cheapest_total = childrel -> cheapest_total_path ;
842
861
843
- append_paths = lappend (append_paths , bestinnerjoin );
862
+ append_paths = lappend (append_paths , index_cheapest_total );
844
863
}
845
864
846
865
if (!found_indexscan )
0 commit comments