Tengo las siguientes definiciones de tabla e índice:
CREATE TABLE munkalap (
munkalap_id serial PRIMARY KEY,
...
);
CREATE TABLE munkalap_lepes (
munkalap_lepes_id serial PRIMARY KEY,
munkalap_id integer REFERENCES munkalap (munkalap_id),
...
);
CREATE INDEX idx_munkalap_lepes_munkalap_id ON munkalap_lepes (munkalap_id);
¿Por qué no se utiliza ninguno de los índices en munkalap_id en la siguiente consulta?
EXPLAIN ANALYZE SELECT ml.* FROM munkalap m JOIN munkalap_lepes ml USING (munkalap_id);
QUERY PLAN
Hash Join (cost=119.17..2050.88 rows=38046 width=214) (actual time=0.824..18.011 rows=38046 loops=1)
Hash Cond: (ml.munkalap_id = m.munkalap_id)
-> Seq Scan on munkalap_lepes ml (cost=0.00..1313.46 rows=38046 width=214) (actual time=0.005..4.574 rows=38046 loops=1)
-> Hash (cost=78.52..78.52 rows=3252 width=4) (actual time=0.810..0.810 rows=3253 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 115kB
-> Seq Scan on munkalap m (cost=0.00..78.52 rows=3252 width=4) (actual time=0.003..0.398 rows=3253 loops=1)
Total runtime: 19.786 ms
Es lo mismo incluso si agrego un filtro:
EXPLAIN ANALYZE SELECT ml.* FROM munkalap m JOIN munkalap_lepes ml USING (munkalap_id) WHERE NOT lezarva;
QUERY PLAN
Hash Join (cost=79.60..1545.79 rows=1006 width=214) (actual time=0.616..10.824 rows=964 loops=1)
Hash Cond: (ml.munkalap_id = m.munkalap_id)
-> Seq Scan on munkalap_lepes ml (cost=0.00..1313.46 rows=38046 width=214) (actual time=0.007..5.061 rows=38046 loops=1)
-> Hash (cost=78.52..78.52 rows=86 width=4) (actual time=0.587..0.587 rows=87 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 4kB
-> Seq Scan on munkalap m (cost=0.00..78.52 rows=86 width=4) (actual time=0.014..0.560 rows=87 loops=1)
Filter: (NOT lezarva)
Total runtime: 10.911 ms
HeapTupleHeader
(23 bytes por fila) + máscara de bits NULL + alineación de acuerdo con MAXALIGN. Finalmente, una cantidad desconocida de relleno debido a la alineación de datos dependiendo de los tipos de datos de las columnas y su secuencia. En total, no hay más de 33 filas en una página de 8 kb en este caso. (Sin tener en cuenta TOAST.)EXPLAIN ANALYZE SELECT foo from bar
con una tabla ficticia básica para verificar. Además, el espacio real en el disco depende de la alineación de datos, lo que sería difícil de tener en cuenta cuando solo se recuperan algunas filas. El ancho de fila enEXPLAIN
representa el requisito de espacio básico para el conjunto de columnas recuperado.Está recuperando todas las filas de ambas tablas, por lo que no hay un beneficio real al usar una exploración de índice. Una exploración de índice solo tiene sentido si selecciona solo unas pocas filas de una tabla (generalmente menos del 10% -15%)
fuente
(lezarva, munkalap_id)
y es lo suficientemente selectivo, entonces puede usarse. EsoNOT
hace que sea menos probable.