Tweak planner to use a minimum size estimate of 10 pages for a

never-yet-vacuumed relation.  This restores the pre-8.0 behavior of
avoiding seqscans during initial data loading, while still allowing
reasonable optimization after a table has been vacuumed.  Several
regression test cases revert to 7.4-like behavior, which is probably
a good sign.  Per gripes from Keith Browne and others.
This commit is contained in:
Tom Lane 2005-03-24 19:14:49 +00:00
parent 7604267de8
commit 208ec47ba3
4 changed files with 71 additions and 46 deletions

View File

@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.100 2004/12/31 22:00:23 pgsql Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.101 2005/03/24 19:14:49 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -234,7 +234,32 @@ estimate_rel_size(Relation rel, int32 *attr_widths,
case RELKIND_INDEX: case RELKIND_INDEX:
case RELKIND_TOASTVALUE: case RELKIND_TOASTVALUE:
/* it has storage, ok to call the smgr */ /* it has storage, ok to call the smgr */
*pages = curpages = RelationGetNumberOfBlocks(rel); curpages = RelationGetNumberOfBlocks(rel);
/*
* HACK: if the relation has never yet been vacuumed, use a
* minimum estimate of 10 pages. This emulates a desirable
* aspect of pre-8.0 behavior, which is that we wouldn't assume
* a newly created relation is really small, which saves us from
* making really bad plans during initial data loading. (The
* plans are not wrong when they are made, but if they are cached
* and used again after the table has grown a lot, they are bad.)
* It would be better to force replanning if the table size has
* changed a lot since the plan was made ... but we don't
* currently have any infrastructure for redoing cached plans at
* all, so we have to kluge things here instead.
*
* We approximate "never vacuumed" by "has relpages = 0", which
* means this will also fire on genuinely empty relations. Not
* great, but fortunately that's a seldom-seen case in the real
* world, and it shouldn't degrade the quality of the plan too
* much anyway to err in this direction.
*/
if (curpages < 10 && rel->rd_rel->relpages == 0)
curpages = 10;
/* report estimated # pages */
*pages = curpages;
/* quick exit if rel is clearly empty */ /* quick exit if rel is clearly empty */
if (curpages == 0) if (curpages == 0)
{ {

View File

@ -214,13 +214,13 @@ SELECT '' AS "xxx", t1.a, t2.e
WHERE t1.a = t2.d; WHERE t1.a = t2.d;
xxx | a | e xxx | a | e
-----+---+---- -----+---+----
| 0 |
| 1 | -1 | 1 | -1
| 2 | 2 | 2 | 2
| 3 | -3
| 2 | 4 | 2 | 4
| 3 | -3
| 5 | -5 | 5 | -5
| 5 | -5 | 5 | -5
| 0 |
(7 rows) (7 rows)
-- --
@ -1567,13 +1567,13 @@ SELECT '' AS "xxx", *
FROM J1_TBL INNER JOIN J2_TBL USING (i); FROM J1_TBL INNER JOIN J2_TBL USING (i);
xxx | i | j | t | k xxx | i | j | t | k
-----+---+---+-------+---- -----+---+---+-------+----
| 0 | | zero |
| 1 | 4 | one | -1 | 1 | 4 | one | -1
| 2 | 3 | two | 4
| 2 | 3 | two | 2 | 2 | 3 | two | 2
| 2 | 3 | two | 4
| 3 | 2 | three | -3 | 3 | 2 | three | -3
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 0 | | zero |
(7 rows) (7 rows)
-- Same as above, slightly different syntax -- Same as above, slightly different syntax
@ -1581,13 +1581,13 @@ SELECT '' AS "xxx", *
FROM J1_TBL JOIN J2_TBL USING (i); FROM J1_TBL JOIN J2_TBL USING (i);
xxx | i | j | t | k xxx | i | j | t | k
-----+---+---+-------+---- -----+---+---+-------+----
| 0 | | zero |
| 1 | 4 | one | -1 | 1 | 4 | one | -1
| 2 | 3 | two | 4
| 2 | 3 | two | 2 | 2 | 3 | two | 2
| 2 | 3 | two | 4
| 3 | 2 | three | -3 | 3 | 2 | three | -3
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 0 | | zero |
(7 rows) (7 rows)
SELECT '' AS "xxx", * SELECT '' AS "xxx", *
@ -1623,35 +1623,35 @@ SELECT '' AS "xxx", *
FROM J1_TBL NATURAL JOIN J2_TBL; FROM J1_TBL NATURAL JOIN J2_TBL;
xxx | i | j | t | k xxx | i | j | t | k
-----+---+---+-------+---- -----+---+---+-------+----
| 0 | | zero |
| 1 | 4 | one | -1 | 1 | 4 | one | -1
| 2 | 3 | two | 4
| 2 | 3 | two | 2 | 2 | 3 | two | 2
| 2 | 3 | two | 4
| 3 | 2 | three | -3 | 3 | 2 | three | -3
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 0 | | zero |
(7 rows) (7 rows)
SELECT '' AS "xxx", * SELECT '' AS "xxx", *
FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d); FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (a, d);
xxx | a | b | c | d xxx | a | b | c | d
-----+---+---+-------+---- -----+---+---+-------+----
| 0 | | zero |
| 1 | 4 | one | -1 | 1 | 4 | one | -1
| 2 | 3 | two | 4
| 2 | 3 | two | 2 | 2 | 3 | two | 2
| 2 | 3 | two | 4
| 3 | 2 | three | -3 | 3 | 2 | three | -3
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 0 | | zero |
(7 rows) (7 rows)
SELECT '' AS "xxx", * SELECT '' AS "xxx", *
FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a); FROM J1_TBL t1 (a, b, c) NATURAL JOIN J2_TBL t2 (d, a);
xxx | a | b | c | d xxx | a | b | c | d
-----+---+---+------+--- -----+---+---+------+---
| 0 | | zero |
| 2 | 3 | two | 2 | 2 | 3 | two | 2
| 4 | 1 | four | 2 | 4 | 1 | four | 2
| 0 | | zero |
(3 rows) (3 rows)
-- mismatch number of columns -- mismatch number of columns
@ -1660,13 +1660,13 @@ SELECT '' AS "xxx", *
FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a); FROM J1_TBL t1 (a, b) NATURAL JOIN J2_TBL t2 (a);
xxx | a | b | t | k xxx | a | b | t | k
-----+---+---+-------+---- -----+---+---+-------+----
| 0 | | zero |
| 1 | 4 | one | -1 | 1 | 4 | one | -1
| 2 | 3 | two | 4
| 2 | 3 | two | 2 | 2 | 3 | two | 2
| 2 | 3 | two | 4
| 3 | 2 | three | -3 | 3 | 2 | three | -3
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 0 | | zero |
(7 rows) (7 rows)
-- --
@ -1676,22 +1676,22 @@ SELECT '' AS "xxx", *
FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i); FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.i);
xxx | i | j | t | i | k xxx | i | j | t | i | k
-----+---+---+-------+---+---- -----+---+---+-------+---+----
| 0 | | zero | 0 |
| 1 | 4 | one | 1 | -1 | 1 | 4 | one | 1 | -1
| 2 | 3 | two | 2 | 4
| 2 | 3 | two | 2 | 2 | 2 | 3 | two | 2 | 2
| 2 | 3 | two | 2 | 4
| 3 | 2 | three | 3 | -3 | 3 | 2 | three | 3 | -3
| 5 | 0 | five | 5 | -5 | 5 | 0 | five | 5 | -5
| 5 | 0 | five | 5 | -5 | 5 | 0 | five | 5 | -5
| 0 | | zero | 0 |
(7 rows) (7 rows)
SELECT '' AS "xxx", * SELECT '' AS "xxx", *
FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k); FROM J1_TBL JOIN J2_TBL ON (J1_TBL.i = J2_TBL.k);
xxx | i | j | t | i | k xxx | i | j | t | i | k
-----+---+---+------+---+--- -----+---+---+------+---+---
| 0 | | zero | | 0
| 2 | 3 | two | 2 | 2 | 2 | 3 | two | 2 | 2
| 4 | 1 | four | 2 | 4 | 4 | 1 | four | 2 | 4
| 0 | | zero | | 0
(3 rows) (3 rows)
-- --
@ -1760,13 +1760,13 @@ SELECT '' AS "xxx", *
FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i); FROM J1_TBL RIGHT OUTER JOIN J2_TBL USING (i);
xxx | i | j | t | k xxx | i | j | t | k
-----+---+---+-------+---- -----+---+---+-------+----
| 0 | | zero |
| 1 | 4 | one | -1 | 1 | 4 | one | -1
| 2 | 3 | two | 2 | 2 | 3 | two | 2
| 3 | 2 | three | -3
| 2 | 3 | two | 4 | 2 | 3 | two | 4
| 3 | 2 | three | -3
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 0 | | zero |
| | | | | | | |
| | | | 0 | | | | 0
(9 rows) (9 rows)
@ -1775,13 +1775,13 @@ SELECT '' AS "xxx", *
FROM J1_TBL RIGHT JOIN J2_TBL USING (i); FROM J1_TBL RIGHT JOIN J2_TBL USING (i);
xxx | i | j | t | k xxx | i | j | t | k
-----+---+---+-------+---- -----+---+---+-------+----
| 0 | | zero |
| 1 | 4 | one | -1 | 1 | 4 | one | -1
| 2 | 3 | two | 2 | 2 | 3 | two | 2
| 3 | 2 | three | -3
| 2 | 3 | two | 4 | 2 | 3 | two | 4
| 3 | 2 | three | -3
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 5 | 0 | five | -5 | 5 | 0 | five | -5
| 0 | | zero |
| | | | | | | |
| | | | 0 | | | | 0
(9 rows) (9 rows)

View File

@ -349,184 +349,184 @@ insert into t values(3,array[3],'b');
select f3, myaggp01a(*) from t group by f3; select f3, myaggp01a(*) from t group by f3;
f3 | myaggp01a f3 | myaggp01a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggp03a(*) from t group by f3; select f3, myaggp03a(*) from t group by f3;
f3 | myaggp03a f3 | myaggp03a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggp03b(*) from t group by f3; select f3, myaggp03b(*) from t group by f3;
f3 | myaggp03b f3 | myaggp03b
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggp05a(f1) from t group by f3; select f3, myaggp05a(f1) from t group by f3;
f3 | myaggp05a f3 | myaggp05a
----+----------- ----+-----------
b | {1,2,3}
c | {1,2} c | {1,2}
a | {1,2,3} a | {1,2,3}
b | {1,2,3}
(3 rows) (3 rows)
select f3, myaggp06a(f1) from t group by f3; select f3, myaggp06a(f1) from t group by f3;
f3 | myaggp06a f3 | myaggp06a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggp08a(f1) from t group by f3; select f3, myaggp08a(f1) from t group by f3;
f3 | myaggp08a f3 | myaggp08a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggp09a(f1) from t group by f3; select f3, myaggp09a(f1) from t group by f3;
f3 | myaggp09a f3 | myaggp09a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggp09b(f1) from t group by f3; select f3, myaggp09b(f1) from t group by f3;
f3 | myaggp09b f3 | myaggp09b
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggp10a(f1) from t group by f3; select f3, myaggp10a(f1) from t group by f3;
f3 | myaggp10a f3 | myaggp10a
----+----------- ----+-----------
b | {1,2,3}
c | {1,2} c | {1,2}
a | {1,2,3} a | {1,2,3}
b | {1,2,3}
(3 rows) (3 rows)
select f3, myaggp10b(f1) from t group by f3; select f3, myaggp10b(f1) from t group by f3;
f3 | myaggp10b f3 | myaggp10b
----+----------- ----+-----------
b | {1,2,3}
c | {1,2} c | {1,2}
a | {1,2,3} a | {1,2,3}
b | {1,2,3}
(3 rows) (3 rows)
select f3, myaggp20a(f1) from t group by f3; select f3, myaggp20a(f1) from t group by f3;
f3 | myaggp20a f3 | myaggp20a
----+----------- ----+-----------
b | {1,2,3}
c | {1,2} c | {1,2}
a | {1,2,3} a | {1,2,3}
b | {1,2,3}
(3 rows) (3 rows)
select f3, myaggp20b(f1) from t group by f3; select f3, myaggp20b(f1) from t group by f3;
f3 | myaggp20b f3 | myaggp20b
----+----------- ----+-----------
b | {1,2,3}
c | {1,2} c | {1,2}
a | {1,2,3} a | {1,2,3}
b | {1,2,3}
(3 rows) (3 rows)
select f3, myaggn01a(*) from t group by f3; select f3, myaggn01a(*) from t group by f3;
f3 | myaggn01a f3 | myaggn01a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggn01b(*) from t group by f3; select f3, myaggn01b(*) from t group by f3;
f3 | myaggn01b f3 | myaggn01b
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggn03a(*) from t group by f3; select f3, myaggn03a(*) from t group by f3;
f3 | myaggn03a f3 | myaggn03a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggn05a(f1) from t group by f3; select f3, myaggn05a(f1) from t group by f3;
f3 | myaggn05a f3 | myaggn05a
----+----------- ----+-----------
b | {1,2,3}
c | {1,2} c | {1,2}
a | {1,2,3} a | {1,2,3}
b | {1,2,3}
(3 rows) (3 rows)
select f3, myaggn05b(f1) from t group by f3; select f3, myaggn05b(f1) from t group by f3;
f3 | myaggn05b f3 | myaggn05b
----+----------- ----+-----------
b | {1,2,3}
c | {1,2} c | {1,2}
a | {1,2,3} a | {1,2,3}
b | {1,2,3}
(3 rows) (3 rows)
select f3, myaggn06a(f1) from t group by f3; select f3, myaggn06a(f1) from t group by f3;
f3 | myaggn06a f3 | myaggn06a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggn06b(f1) from t group by f3; select f3, myaggn06b(f1) from t group by f3;
f3 | myaggn06b f3 | myaggn06b
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggn08a(f1) from t group by f3; select f3, myaggn08a(f1) from t group by f3;
f3 | myaggn08a f3 | myaggn08a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggn08b(f1) from t group by f3; select f3, myaggn08b(f1) from t group by f3;
f3 | myaggn08b f3 | myaggn08b
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggn09a(f1) from t group by f3; select f3, myaggn09a(f1) from t group by f3;
f3 | myaggn09a f3 | myaggn09a
----+----------- ----+-----------
b | {}
c | {} c | {}
a | {} a | {}
b | {}
(3 rows) (3 rows)
select f3, myaggn10a(f1) from t group by f3; select f3, myaggn10a(f1) from t group by f3;
f3 | myaggn10a f3 | myaggn10a
----+----------- ----+-----------
b | {1,2,3}
c | {1,2} c | {1,2}
a | {1,2,3} a | {1,2,3}
b | {1,2,3}
(3 rows) (3 rows)

View File

@ -1124,8 +1124,8 @@ insert into shoelace values ('sl10', 1000, 'magenta', 40.0, 'inch', 0.0);
SELECT * FROM shoelace_obsolete; SELECT * FROM shoelace_obsolete;
sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
------------+----------+------------+--------+----------+----------- ------------+----------+------------+--------+----------+-----------
sl10 | 1000 | magenta | 40 | inch | 101.6
sl9 | 0 | pink | 35 | inch | 88.9 sl9 | 0 | pink | 35 | inch | 88.9
sl10 | 1000 | magenta | 40 | inch | 101.6
(2 rows) (2 rows)
SELECT * FROM shoelace_candelete; SELECT * FROM shoelace_candelete;