[Bizgres-general] constraint exclusion (table partitioning) not
working?
Bob Ippolito
bob at redivi.com
Tue Sep 13 02:36:21 GMT 2005
I'm getting a totally bogus query plan with bizgres 0.7.4 for a
partitioned table:
EXPLAIN SELECT
"id",
date_trunc('hour', "timestamp") AS "timestamp",
"mochiTag",
"movieURL",
"movieURLHost"
FROM "ping" WHERE
"id" > '0' AND "timestamp" >= '1969-12-31 16:00:00-08'
ORDER BY "id" LIMIT '1000';
Limit (cost=10224769.58..10224772.08 rows=1000 width=36)
-> Sort (cost=10224769.58..10328540.22 rows=41508256 width=36)
Sort Key: public.ping.id
-> Result (cost=1.43..1772652.20 rows=41508256 width=36)
One-Time Filter: false
-> Append (cost=1.43..1668881.56 rows=41508256
width=36)
-> Bitmap Heap Scan on ping (cost=1.43..13.29
rows=42 width=36)
Recheck Cond: (id > 0::bigint)
Filter: ("timestamp" >= '1969-12-31
16:00:00-08'::timestamp with time zone)
-> Bitmap Index Scan on ping_pkey
(cost=0.00..1.43 rows=124 width=0)
Index Cond: (id > 0::bigint)
-> Seq Scan on ping_20050816 ping
(cost=0.00..25823.00 rows=635274 width=36)
Filter: ((id > 0::bigint) AND
("timestamp" >= '1969-12-31 16:00:00-08'::timestamp with time zone))
-> Seq Scan on ping_20050512 ping
(cost=0.00..1.01 rows=1 width=36)
Filter: ((id > 0::bigint) AND
("timestamp" >= '1969-12-31 16:00:00-08'::timestamp with time zone))
-> Seq Scan on ping_20050514 ping
(cost=0.00..48123.90 rows=1240547 width=36)
Filter: ((id > 0::bigint) AND
("timestamp" >= '1969-12-31 16:00:00-08'::timestamp with time zone))
-> Seq Scan on ping_20050726 ping
(cost=0.00..30969.24 rows=795591 width=36)
Filter: ((id > 0::bigint) AND
("timestamp" >= '1969-12-31 16:00:00-08'::timestamp with time zone))
-> Seq Scan on ping_20050727 ping
(cost=0.00..8317.99 rows=204959 width=36)
Filter: ((id > 0::bigint) AND
("timestamp" >= '1969-12-31 16:00:00-08'::timestamp with time zone))
-> Seq Scan on ping_20050513 ping
(cost=0.00..904.77 rows=23314 width=36)
Filter: ((id > 0::bigint) AND
("timestamp" >= '1969-12-31 16:00:00-08'::timestamp with time zone))
-> Seq Scan on ping_20050515 ping
(cost=0.00..45802.06 rows=1180970 width=36)
Filter: ((id > 0::bigint) AND
("timestamp" >= '1969-12-31 16:00:00-08'::timestamp with time zone))
..... there's a lot more of these tables with dumb query plans
They all look like this:
Table "public.ping_20050816"
Column | Type
| Modifiers
------------------------+--------------------------
+------------------------------------------------------
id | bigint | not null default
nextval('public.ping_id_seq'::text)
timestamp | timestamp with time zone | not null
..... with more columns that are irrelevant
Indexes:
"ping_20050816_pkey" PRIMARY KEY, btree (id)
"ping_20050816_mochiTag_movieURLHost_timestamp" btree
("mochiTag", "movieURLHost", "timestamp")
"ping_20050816_mochiTag_movieURL_timestamp" btree ("mochiTag",
"movieURL", "timestamp")
"ping_20050816_mochiTag_timestamp" btree ("mochiTag", "timestamp")
Check constraints:
"ping_20050816_id_check" CHECK (id >= 20457247 AND id <= 21092646)
"ping_20050816_timestamp_check" CHECK ("timestamp" >=
'2005-08-16 00:00:00-07'::timestamp with time zone AND "timestamp" <=
'2005-08-16 23:59:59-07'::timestamp with time zone)
Inherits: ping
I would expect that in this case, it should:
1. Use indexes
2. Hopefully know that the tables are strictly ordered on id because
there are no overlaps on check constraints. it should only have to
look in the two first ping tables to find 1000 rows (the first table
is degenerate and only has one row, the rest generally have at least
tens of thousands, some over a million).
I have checked that enable_constraint_exclusion is on (it seems to be
on by default) and everything should be fully vacuumed and analyzed.
The query plan for scanning the empty parent table (ping) is closer
to what I would expect them all to look like (I don't understand why
it wants a bitmap for one column though).
I'm currently doing a pg_restore into CVS HEAD of 8.1, to see what it
does here (hopefully something else!).
-bob
More information about the Bizgres-general
mailing list