Hola a todos,
he creado una tabla de artículos (no está acabada todavía) del
siguiente modo:
===============
--DROP TABLE IF EXISTS mwi.articulos CASCADE;
CREATE TABLE mwi.articulos (
familia varchar(2) NOT NULL,
empresa numeric(5) NOT NULL,
grupo varchar(2) NOT NULL,
subgrupo varchar(2) NOT NULL,
articulo numeric(6) NOT NULL,
nombre varchar(50) NOT NULL,
tipoiva numeric(1),
locpasillo numeric(2),
loccolumna numeric(2),
locestante numeric(2),
CONSTRAINT pk_articulos PRIMARY
KEY(empresa,familia,grupo,subgrupo,articulo) WITH (fillfactor = 90)
)
WITH (FILLFACTOR = 90, OIDS = False);
CREATE UNIQUE INDEX inx_articulos_articulo1 ON mwi.articulos (
empresa,
(familia||grupo||subgrupo||LPAD(CAST(articulo AS text),6,'0'))
);
INSERT INTO mwi.articulos ( empresa, familia, grupo, subgrupo,
articulo, nombre)
VALUES
( 1, 'AC', 'MA', 'P1', 1, 'XXXXXXXXXXXXXXXXX p1-1'),
( 1, 'AC', 'MA', 'P1', 2, 'XXXXXXXXXXXXXXXXX p1-2'),
( 1, 'AC', 'MA', 'P2', 1, 'XXXXXXXXXXXXXXXXX p2-1'),
( 1, 'AC', 'MA', 'P2', 2, 'XXXXXXXXXXXXXXXXX p2-2'),
( 1, 'AC', 'DU', 'P1', 1, 'XXXXXXXXXXXXXXXXX dp1-1'),
( 1, 'AC', 'DU', 'P1', 2, 'XXXXXXXXXXXXXXXXX dp1-2'),
( 1, 'AC', 'DU', 'P2', 1, 'XXXXXXXXXXXXXXXXX dp2-1'),
( 1, 'AC', 'DU', 'P2', 2, 'XXXXXXXXXXXXXXXXX dp2-2'),
( 1, 'PE', 'PI', 'AD', 1, 'XXXXXXXXXXXXXXXXX ad-1'),
( 1, 'PE', 'PI', 'AD', 2, 'XXXXXXXXXXXXXXXXX ad-2'),
( 1, 'PE', 'PI', 'EK', 1, 'XXXXXXXXXXXXXXXXX ek-1'),
( 1, 'PE', 'PI', 'EK', 2, 'XXXXXXXXXXXXXXXXX ek-2'),
( 1, 'PE', 'GO', 'PM', 1, 'XXXXXXXXXXXXXXXXX pm-1'),
( 1, 'PE', 'GO', 'PM', 2, 'XXXXXXXXXXXXXXXXX pm-2'),
( 1, 'PE', 'GO', 'PG', 1, 'XXXXXXXXXXXXXXXXX pg-1'),
( 1, 'PE', 'GO', 'PG', 2, 'XXXXXXXXXXXXXXXXX pg-2');
===============
Con la intención, claro, de que mis consultas usasen este indice.
Pero no lo hacen. Hacen una cosa que no entiendo muy bien, pues
hacen un Seq Scan, quiero suponer que es más facil leer la tabla
entera que hacer la busqueda por el INDICE, pero después hay un Index
Scan que usa la PRIMARY KEY.
Alguien tiene una idea de por qué no se usa el indice
'inx_articulos_articulo1' ?
Aquí la consulta y su EXPLAIN ANALYZE...:
SELECT
a.empresa,
(a.familia|| a.grupo || a.subgrupo || LPAD(CAST(A.articulo AS
text),6,'0')) AS articulo
, a.nombre,
mwi.f_iva(a.empresa, COALESCE(a.tipoiva, b.tipoiva)) AS ivatpc
FROM mwi.articulos A LEFT JOIN mwi.familias b
ON b.empresa = a.empresa
AND b.familia::text = a.familia::text
WHERE
A.empresa = 1 AND
a.familia||a.grupo||a.subgrupo||LPAD(CAST(A.articulo AS
text),6,'0') = 'ACDUP1000001';
Nested Loop Left Join (cost=0.00..9.99 rows=1 width=79) (actual
time=0.505..0.532 rows=1 loops=1)
-> Seq Scan on articulos a (cost=0.00..1.44 rows=1 width=70)
(actual time=0.028..0.051 rows=1 loops=1)
Filter: (((((familia)::text || (grupo)::text) ||
(subgrupo)::text) || lpad((articulo)::text, 6, '0'::text)) =
'ACDUP1000001'::text)
-> Index Scan using pk_familias on familias b (cost=0.00..8.27
rows=1 width=32) (actual time=0.019..0.021 rows=1 loops=1)
Index Cond: ((b.empresa = a.empresa) AND ((b.familia)::text =
(a.familia)::text))
Total runtime: 0.615 ms"
--
TIP 8: explain analyze es tu amigo