atualmente esta consulta não usa um índice mesmo depois que eu criei um:
EXPLAIN ANALYZE SELECT * FROM customer_list WHERE rating = 3 ORDER BY name ASC LIMIT 20 ;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=149.14..149.18 rows=15 width=1156) (actual time=11.307..11.311 rows=20 loops=1)
-> Sort (cost=149.14..149.18 rows=15 width=1156) (actual time=11.305..11.306 rows=20 loops=1)
Sort Key: c.name
Sort Method: top-N heapsort Memory: 28kB
-> Nested Loop (cost=0.28..148.85 rows=15 width=1156) (actual time=0.022..6.403 rows=2977 loops=1)
-> Seq Scan on crm_customer c (cost=0.00..96.24 rows=15 width=674) (actual time=0.009..1.184 rows=2977 loops=1)
Filter: (rating = 3)
Rows Removed by Filter: 2
-> Index Only Scan using crm_address_search_index on crm_address a (cost=0.28..3.50 rows=1 width=498) (actual time=0.001..0.001 rows=1 loops=2977)
Index Cond: (id = c.address_id)
Heap Fetches: 0
Planning time: 0.246 ms
Execution time: 11.353 ms
(13 rows)
Ao desligar o seqscan, set enable_seqscan = false;
ele será executado corretamente (ordenado por nome e muito mais rápido):
EXPLAIN ANALYZE SELECT * FROM customer_list WHERE rating = 3 ORDER BY name ASC LIMIT 20 ;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.56..413.02 rows=15 width=1156) (actual time=0.028..0.103 rows=20 loops=1)
-> Nested Loop (cost=0.56..413.02 rows=15 width=1156) (actual time=0.027..0.101 rows=20 loops=1)
-> Index Scan using crm_customer_name on crm_customer c (cost=0.28..360.41 rows=15 width=674) (actual time=0.018..0.040 rows=20 loops=1)
Filter: (rating = 3)
Rows Removed by Filter: 2
-> Index Only Scan using crm_address_search_index on crm_address a (cost=0.28..3.50 rows=1 width=498) (actual time=0.002..0.002 rows=1 loops=20)
Index Cond: (id = c.address_id)
Heap Fetches: 0
Planning time: 0.190 ms
Execution time: 0.133 ms
(10 rows)
Meu índice real é criado com:
CREATE INDEX crm_customer_name_search_index ON crm_customer (name text_pattern_ops ASC NULLS FIRST );
atualmente eu tinha um índice maior e pensei que esse fosse o problema, mas no entanto não é. (classificação de indexação, também não ajuda)
Você pode encontrar a resposta nas
EXPLAIN ANALYZE
saídas que você postou.Na primeira, o custo estimado da varredura sequencial é
96.24
de , enquanto a varredura de índice tem um custo de360.41
na segunda. É por isso que o planejador decidiu não usar o índice.No entanto, vemos que o tempo de execução é muito melhor no segundo caso. A principal razão pode ser que a estimativa de linha da varredura sequencial é muito ruim - 15 linhas são esperadas em vez de ~3k. Faça um
ANALYZE crm_customer;
e veja se muda - já é possível que o índice seja escolhido.