No Postgres 16, notei o seguinte comportamento "errado" de uso de índice:
Tenho uma tabela (350000 registros) com uma chave primária composta:
CREATE TABLE IF NOT EXISTS public.mytable
(
arflgart integer NOT NULL,
arkeyart character varying(10) COLLATE pg_catalog."default" NOT NULL,
...
CONSTRAINT pk_mytable PRIMARY KEY (arflgart, arkeyart),
...
idx_keyart_flgart
Há também um índice BTREE (arkeyart,arflgart)
e um índice gist
CREATE INDEX IF NOT EXISTS idx_arkeyart ON public.mytable
USING gist (arkeyart COLLATE pg_catalog."default" gist_trgm_ops);
Quando fiz consultas em outra tabela com um LEFT JOIN
to mytable
nas duas chaves primárias:
SELECT *
FROM another_table tab2
LEFT JOIN mytable ON tab2.field1=arflgart AND tab2.field2 = arkeyart
WHERE tab2.field3 > 0
A execução da consulta demora muito porque NÃO usa o índice da chave primária ou o idx_keyart_flgart
, mas usa o índice gist idx_arkeyart
?!?
...
Index Scan using idx_arkeyart on mytable
Index Cond: ((arkeyart)::text = (another_table.field2)::text)
Filter: (arflgart = another_table.field1)
Buffers: shared hit=14,224,232
...
Se eu remover o índice gist, a consulta será imediata.
*** Por que o Postgres não reconhece o índice correto a ser usado?
Este é o plano de execução completo:
"Gather (cost=1000.71..36112.85 rows=59828 width=56) (actual time=6.490..34806.715 rows=60758 loops=1)"
" Workers mytable: 3"
" Workers Launched: 3"
" Buffers: shared hit=14416778"
" -> Nested Loop Left Join (cost=0.71..29130.05 rows=19299 width=56) (actual time=9.918..34723.521 rows=15190 loops=4)"
" Buffers: shared hit=14416778"
" -> Nested Loop Left Join (cost=0.42..22483.10 rows=19299 width=49) (actual time=0.408..236.928 rows=15190 loops=4)"
" Buffers: shared hit=192546"
" -> Parallel Seq Scan on ba_salart001 ba_salart (cost=0.00..12263.89 rows=19299 width=49) (actual time=0.029..80.870 rows=15190 loops=4)"
" Filter: (saqtagia <> '0'::numeric)"
" Rows Removed by Filter: 108773"
" Buffers: shared hit=10258"
" -> Index Only Scan using pk_another_table001 on another_table001 another_table (cost=0.42..0.53 rows=1 width=26) (actual time=0.009..0.009 rows=1 loops=60758)"
" Index Cond: ((ulcodkey = (ba_salart.saunilog)::text) AND (field1 = ba_salart.saflgart) AND (field2 = (ba_salart.sakeyart)::text))"
" Heap Fetches: 7"
" Buffers: shared hit=182288"
" -> Index Scan using idx_arkeyart on mytable001 mytable (cost=0.28..0.33 rows=1 width=22) (actual time=2.268..2.268 rows=1 loops=60758)"
" Index Cond: ((arkeyart)::text = (another_table.field2)::text)"
" Filter: (arflgart = another_table.field1)"
" Buffers: shared hit=14224232"
"Planning:"
" Buffers: shared hit=890"
"Planning Time: 14.776 ms"
"Execution Time: 34813.134 ms"