How avoid the scan in the main table

橙三吉。 提交于 2020-01-07 06:31:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!