2017-09-15 4 views
1

Aidez-moi à comprendre pourquoi la requête évaluée à l'aide de l'instruction préparée ne respecte pas l'indexation.pourquoi l'instruction PREPARE ne respecte pas INDEXing

\d+ lerg; 

                 Table "public.lerg" 
    Column |   Type    |      Modifiers      | Storage | Stats target | Description 
------------+-----------------------------+---------------------------------------------------+----------+--------------+------------- 
id   | bigint      | not null default nextval('lerg_id_seq'::regclass) | plain |    | 
lata  | character varying   | not null           | extended |    | 
npa  | character varying(3)  |             | extended |    | 
nxx  | character varying(3)  |             | extended |    | 
block  | character varying(1)  |             | extended |    | 
ocn  | character varying   |             | extended |    | 
created_at | timestamp without time zone | not null default now()       | plain |    | 
Indexes: 
    "lerg_pkey" PRIMARY KEY, btree (id) 
    "lerg_npa_nxx_block" UNIQUE, btree (npa, nxx, block) 

Nombre total d'enregistrements dans la table LERG.

select count(*) from lerg; 
=> 199846 

La déclaration préparée

prepare fetch_lata(char(3), char(3), char(1)) as select lata from lerg where npa=$1 and nxx=$2 and block=$3; 

exécuter l'instruction.

explain analyze execute fetch_lata('365','406','A'); 
                QUERY PLAN 
--------------------------------------------------------------------------------------------------------------------- 
Seq Scan on lerg (cost=0.00..5163.31 rows=1 width=6) (actual time=0.014..27.530 rows=1 loops=1) 
    Filter: (((npa)::bpchar = '365'::bpchar) AND ((nxx)::bpchar = '406'::bpchar) AND ((block)::bpchar = 'A'::bpchar)) 
    Rows Removed by Filter: 199845 
Execution time: 27.560 ms 
(4 rows) 

Impossible de comprendre.

  • Pourquoi la numérisation de table?
  • Pourquoi les index ne sont-ils pas utilisés?

Sur une autre note.

explain analyze select lata from lerg where npa='365' and nxx='406' and block='A'; 
                 QUERY PLAN 
------------------------------------------------------------------------------------------------------------------------- 
Index Scan using lerg_npa_nxx_block on lerg (cost=0.42..8.44 rows=1 width=6) (actual time=0.016..0.016 rows=1 loops=1) 
    Index Cond: (((npa)::text = '365'::text) AND ((nxx)::text = '406'::text) AND ((block)::text = 'A'::text)) 
Planning time: 0.081 ms 
Execution time: 0.033 ms 
(4 rows) 

Q. Une requête select avec une indexation appropriée bat haut la main la requête de déclaration préparée, pourquoi?

Q. N'existe-t-il aucun avantage à utiliser l'instruction PREPARED pour une requête simple comme ci-dessus. Juste une tête de la différence pour l'enregistrement de la requête 10_000 était si élevé que je dois abandonner l'instruction préparée.

Le résultat de l'enregistrement de requête 10_000.

        user  system  total  real 
pg_without_prepared_statmt  0.050000 0.080000 0.130000 ( 0.935051) 

pg_with_prepared_statmt   0.090000 0.110000 0.200000 ( 5.707693) 

Détails de la machine.

Postgres Version : 9.5.9 
Mac OS: 10.12.5 

Répondre

2

Le problème est que les paramètres de votre déclaration préparée sont de type character (le même que bpchar), de sorte que l'opérateur d'égalité pour ce type est utilisé, et l'indice ne peut pas être utilisé parce qu'il est défini par character varying .

Si vous modifiez les arguments de l'instruction préparée en varchar, cela devrait fonctionner comme prévu.

+0

Je vais essayer ça .. – Ratatouille