From 0c0151a3ec78a3e17200e816c02508d9269b68d7 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 15 Apr 1999 04:08:07 +0000 Subject: [PATCH] Initialize reltuples = 1000, relpages = 10 in a newly created relation, rather than zeroes. This prevents the optimizer from making foolish choices (ie, using nested-loop plans) on never-yet-vacuumed tables. This is a hack, of course. Keeping accurate track of these statistics would be a cleaner solution, but it's far from clear that it'd be worth the cost of doing so. In any case we're not going to do that for 6.5. In the meantime, this quick hack provides a useful performance improvement in the regression tests and in many real-world scenarios. --- src/backend/catalog/heap.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 53039f031a..6db517b076 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.76 1999/03/17 22:52:48 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.77 1999/04/15 04:08:07 tgl Exp $ * * * INTERFACE ROUTINES @@ -661,7 +661,29 @@ AddNewRelationTuple(Relation pg_class_desc, new_rel_reltup = new_rel_desc->rd_rel; /* CHECK should get new_rel_oid first via an insert then use XXX */ - /* new_rel_reltup->reltuples = 1; *//* XXX */ + + /* ---------------- + * Here we insert bogus estimates of the size of the new relation. + * In reality, of course, the new relation has 0 tuples and pages, + * and if we were tracking these statistics accurately then we'd + * set the fields that way. But at present the stats will be updated + * only by VACUUM or CREATE INDEX, and the user might insert a lot of + * tuples before he gets around to doing either of those. So, instead + * of saying the relation is empty, we insert guesstimates. The point + * is to keep the optimizer from making really stupid choices on + * never-yet-vacuumed tables; so the estimates need only be large + * enough to discourage the optimizer from using nested-loop plans. + * With this hack, nested-loop plans will be preferred only after + * the table has been proven to be small by VACUUM or CREATE INDEX. + * (NOTE: if user does CREATE TABLE, then CREATE INDEX, then loads + * the table, he still loses until he vacuums, because CREATE INDEX + * will set reltuples to zero. Can't win 'em all. Maintaining the + * stats on-the-fly would solve the problem, but the overhead of that + * would likely cost more than it'd save.) + * ---------------- + */ + new_rel_reltup->relpages = 10; /* bogus estimates */ + new_rel_reltup->reltuples = 1000; new_rel_reltup->relowner = GetUserId(); new_rel_reltup->relkind = relkind;