问题
I have a table partitioned using inherit in multiple tables for days.
There is one insert trigger to insert the data to the proper table, so in theory the avl table shouldnt have any data
CREATE OR REPLACE FUNCTION avl_db.avl_insert_trigger()
RETURNS trigger AS
$BODY$
BEGIN
IF ( NEW.event_time >= '2017-06-01 00:00:00' AND NEW.event_time < '2017-06-02 00:00:00' ) THEN
INSERT INTO avl_db.avl_20170601 VALUES (NEW.*);
ELSEIF ( NEW.event_time >= '2017-06-02 00:00:00' AND NEW.event_time < '2017-06-03 00:00:00' ) THEN
INSERT INTO avl_db.avl_20170602 VALUES (NEW.*);
ELSEIF ( NEW.event_time >= '2017-06-03 00:00:00' AND NEW.event_time < '2017-06-04 00:00:00' ) THEN
INSERT INTO avl_db.avl_20170603 VALUES (NEW.*);
ELSEIF ( NEW.event_time >= '2017-06-04 00:00:00' AND NEW.event_time < '2017-06-05 00:00:00' ) THEN
INSERT INTO avl_db.avl_20170604 VALUES (NEW.*);
ELSEIF ( NEW.event_time >= '2017-06-05 00:00:00' AND NEW.event_time < '2017-06-06 00:00:00' ) THEN
INSERT INTO avl_db.avl_20170605 VALUES (NEW.*);
....
ELSE
RAISE EXCEPTION 'Date out of range.';
END IF;
RETURN NULL;
Every table has a check constraint and index so only check the table with the right date
CONSTRAINT avl_20170605_event_time_check
CHECK (event_time >= '2017-06-05 00:00:00'::timestamp without time zone
AND event_time < '2017-06-06 00:00:00'::timestamp without time zone)
CREATE INDEX avl_20170605__event_time_idx
ON avl_db.avl_20170605
USING btree
(event_time);
The thing is when do select using the event_time
to filter still do some operation over the main avl
table.
explain analyze
SELECT *
FROM avl_db.avl
WHERE event_time between '2017-06-05 09:40:44'::timestamp without time zone - '6 minute'::interval
AND '2017-06-05 09:40:44'::timestamp without time zone - '1 minute'::interval
You can see use the index from avl_20170605__event_time_idx
and ignore the rest of the tables, but also try to do a Seq Scan on avl
.
Append (cost=0.00..720.98 rows=7724 width=16) (actual time=0.044..5.523 rows=7851 loops=1)
-> Seq Scan on avl (cost=0.00..0.00 rows=1 width=16) (actual time=0.001..0.001 rows=0 loops=1)
Filter: ((event_time >= '2017-06-05 09:34:44'::timestamp without time zone) AND (event_time <= '2017-06-05 09:39:44'::timestamp without time zone))
-> Index Scan using avl_20170605__event_time_idx on avl_20170605 (cost=0.42..720.98 rows=7723 width=16) (actual time=0.042..5.110 rows=7851 loops=1)
Index Cond: ((event_time >= '2017-06-05 09:34:44'::timestamp without time zone) AND (event_time <= '2017-06-05 09:39:44'::timestamp without time zone))
Planning time: 3.050 ms
Execution time: 5.737 ms
I'm wondering if there is a way optimizer stop trying to scan and append the table avl
.
回答1:
That is normal and as it should be.
Every scan on a partitioned table will also scan the (usually empty) parent table, since it doesn't (and cannot) have a CHECK
constraint like the child tables have.
You can see that this scan doesn't contribute any time to the overall query duration.
来源:https://stackoverflow.com/questions/44954294/how-avoid-the-scan-in-the-main-table