0

J'ai une table partitionnée en utilisant l'héritage de plusieurs tables pendant plusieurs jours.Comment éviter l'analyse dans la table principale

enter image description here

Il y a un déclencheur d'insertion pour insérer les données à la table appropriée, donc en théorie la table AVL ne devrait pas avoir des données

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; 

Chaque table a une contrainte de vérification et de l'index de façon seulement vérifier la table avec la bonne 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); 

la chose est quand ne sélectionnez à l'aide du event_time pour filtrer encore d o certaines opérations sur la table principale 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 

Vous pouvez voir utiliser l'index de avl_20170605__event_time_idx et ignorer le reste des tables, mais aussi faire une analyse sur Seq 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 

Je me demande s'il y a un arrêt optimiseur de façon à essayer de scanner et d'ajouter la table avl.

+1

Pour une seule ligne, effectuer un 'Seq Scan' est le seul moyen efficace. –

+0

Aussi, montrez-nous votre déclencheur de création - est-ce un avant ou après? –

+0

@a_horse_with_no_name Je vois le 'row = 1'. Mais cela n'a aucun sens, il ne devrait pas y avoir de lignes là-bas. Y a-t-il un moyen de voir quelle rangée est là? Et ma question est plus comme quand j'ajoute la contrainte 'CHECK' l'optimiseur vérifie seulement une table. Alors peut-être que je peux définir donc ignorer la table principale. –

Répondre

1

C'est normal et comme il se doit. Chaque analyse sur une table partitionnée analyse également la table parent (généralement vide), car elle n'a pas (et ne peut pas) avoir une contrainte CHECK comme les tables enfants ont.

Vous pouvez voir que cette analyse ne contribue pas à la durée globale de la requête.