Terry Yapt escribió:
Terry Yapt escribió:
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




Perdón... (grrrrrrrrrr...) la PRIMARY KEY de las estadisticas, es de una tabla que no me he acordado de quitar del ejemplo. Lo siento.

La pregunta, sin embargo, sigue siendo la misma. Por qué no se usa el indice y, en su lugar, se usa un Seq Scan ???

Voy a tratar, por el momento, de llenar la tabla con muchos más datos, a ver si consigo que se use el indice.

Gracias.
--
TIP 2: puedes desuscribirte de todas las listas simultáneamente
   (envía "unregister TuDirecciónDeCorreo" a majord...@postgresql.org)


Bueno, pues yo he empezado y yo lo acabo. Tras insertar 200 lineas de artículos, aquí el resultado:

Total runtime: 0.141 ms
Index Cond: ((empresa = 1::numeric) AND (((((familia)::text || (grupo)::text) || (subgrupo)::text) || lpad((articulo)::text, 6, '0'::text)) = 'ACDUP1000001'::text)) Index Scan using inx_articulos_articulo1 on articulos a (cost=0.01..8.30 rows=1 width=47) (actual time=0.053..0.056 rows=1 loops=1)

Saludos.

--
TIP 3: Si encontraste la respuesta a tu problema, publícala, otros te lo 
agradecerán

Responder a