0

複数のテーブルを数日間継承してテーブルを分割しました。メインテーブルのスキャンを避ける方法

enter image description here

理論的にはAVLテーブルは、任意のデータ

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; 

すべてのテーブルには、チェック制約とそのインデックスのみを持っているを持っているはずのよう、適切なテーブルにデータを挿入する1つの挿入トリガーがあります右の日付のものをd、まだフィルタリングするevent_timeを使用して選択しないときである

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); 

でテーブルをチェックoメインのavlテーブルに対する何らかの操作。

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 

あなたはavl_20170605__event_time_idxからインデックスを使用して、テーブルの残りの部分を無視参照するだけでなく、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 

テーブルavlをスキャンして追加しようとしている方法オプティマイザ停止がある場合、私は思ったんだけど。

+1

ただ1列の場合、 'Seq Scan 'を実行するのが唯一の効率的な方法です。 –

+0

さらに、作成トリガを表示します - それは前か後ですか? –

+0

@a_horse_with_no_name私は '行= 1'を参照してください。しかし、それは意味をなさない、そこに行があってはならない。私はそこに行が何かを見ることができる方法はありますか?そして、私の質問は、オプティマイザが1つのテーブルだけをチェックする 'CHECK'制約を追加するときによく似ています。だから多分私はメインテーブルを無視するように設定することができます。 –

答えて

1

これは正常であり、そうである必要があります。

パーティションテーブルのすべてのスキャンは、子テーブルと同じようにCHECKという制約がないため、(通常は空の)親テーブルもスキャンします。

このスキャンは、全体的なクエリの実行時間に影響しないことがわかります。

関連する問題