diff options
Diffstat (limited to 'src/backend/optimizer/path/costsize.c')
| -rw-r--r-- | src/backend/optimizer/path/costsize.c | 81 |
1 files changed, 70 insertions, 11 deletions
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index fffa25dd84..cd289423ec 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -54,7 +54,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.165 2006/08/02 01:59:45 joe Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.166 2006/09/19 22:49:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -288,7 +288,8 @@ cost_index(IndexPath *path, PlannerInfo *root, pages_fetched = index_pages_fetched(tuples_fetched * num_scans, baserel->pages, - index->pages); + (double) index->pages, + root); run_cost += (pages_fetched * random_page_cost) / num_scans; } @@ -300,7 +301,8 @@ cost_index(IndexPath *path, PlannerInfo *root, */ pages_fetched = index_pages_fetched(tuples_fetched, baserel->pages, - index->pages); + (double) index->pages, + root); /* max_IO_cost is for the perfectly uncorrelated case (csquared=0) */ max_IO_cost = pages_fetched * random_page_cost; @@ -369,13 +371,18 @@ cost_index(IndexPath *path, PlannerInfo *root, * b = # buffer pages available (we include kernel space here) * * We assume that effective_cache_size is the total number of buffer pages - * available for both table and index, and pro-rate that space between the - * table and index. (Ideally other_pages should include all the other - * tables and indexes used by the query too; but we don't have a good way - * to get that number here.) + * available for the whole query, and pro-rate that space across all the + * tables in the query and the index currently under consideration. (This + * ignores space needed for other indexes used by the query, but since we + * don't know which indexes will get used, we can't estimate that very well; + * and in any case counting all the tables may well be an overestimate, since + * depending on the join plan not all the tables may be scanned concurrently.) * * The product Ns is the number of tuples fetched; we pass in that - * product rather than calculating it here. + * product rather than calculating it here. "pages" is the number of pages + * in the object under consideration (either an index or a table). + * "index_pages" is the amount to add to the total table space, which was + * computed for us by query_planner. * * Caller is expected to have ensured that tuples_fetched is greater than zero * and rounded to integer (see clamp_row_est). The result will likewise be @@ -383,17 +390,23 @@ cost_index(IndexPath *path, PlannerInfo *root, */ double index_pages_fetched(double tuples_fetched, BlockNumber pages, - BlockNumber other_pages) + double index_pages, PlannerInfo *root) { double pages_fetched; + double total_pages; double T, b; /* T is # pages in table, but don't allow it to be zero */ T = (pages > 1) ? (double) pages : 1.0; + /* Compute number of pages assumed to be competing for cache space */ + total_pages = root->total_table_pages + index_pages; + total_pages = Max(total_pages, 1.0); + Assert(T <= total_pages); + /* b is pro-rated share of effective_cache_size */ - b = (double) effective_cache_size * T / (T + (double) other_pages); + b = (double) effective_cache_size * T / total_pages; /* force it positive and integral */ if (b <= 1.0) b = 1.0; @@ -431,6 +444,51 @@ index_pages_fetched(double tuples_fetched, BlockNumber pages, } /* + * get_indexpath_pages + * Determine the total size of the indexes used in a bitmap index path. + * + * Note: if the same index is used more than once in a bitmap tree, we will + * count it multiple times, which perhaps is the wrong thing ... but it's + * not completely clear, and detecting duplicates is difficult, so ignore it + * for now. + */ +static double +get_indexpath_pages(Path *bitmapqual) +{ + double result = 0; + ListCell *l; + + if (IsA(bitmapqual, BitmapAndPath)) + { + BitmapAndPath *apath = (BitmapAndPath *) bitmapqual; + + foreach(l, apath->bitmapquals) + { + result += get_indexpath_pages((Path *) lfirst(l)); + } + } + else if (IsA(bitmapqual, BitmapOrPath)) + { + BitmapOrPath *opath = (BitmapOrPath *) bitmapqual; + + foreach(l, opath->bitmapquals) + { + result += get_indexpath_pages((Path *) lfirst(l)); + } + } + else if (IsA(bitmapqual, IndexPath)) + { + IndexPath *ipath = (IndexPath *) bitmapqual; + + result = (double) ipath->indexinfo->pages; + } + else + elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual)); + + return result; +} + +/* * cost_bitmap_heap_scan * Determines and returns the cost of scanning a relation using a bitmap * index-then-heap plan. @@ -494,7 +552,8 @@ cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel, pages_fetched = index_pages_fetched(tuples_fetched * num_scans, baserel->pages, - 0 /* XXX total index size? */); + get_indexpath_pages(bitmapqual), + root); pages_fetched /= num_scans; } else |
