2015-07-27 5 views
0

Вот мой стол (на самом деле материализованное представление), в Postgres 9.4:Почему Postgres не использует мой индекс?

Materialized view "public.vw_presentation_summary" 
     Column  |   Type   | Modifiers 
-------------------+-----------------------+----------- 
processing_date | date     | 
presentation_code | character varying(15) | 
items    | numeric    | 
cost    | double precision  | 
Indexes: 
    "vw_idx_presentation_summary" btree (presentation_code) 

Я просто запустить VACUUM ANALYZE vw_presentation_summary, поэтому планировщик запросов должен быть в курсе.

Теперь, если я бегу explain (analyse, buffers) select * from vw_presentation_summary where presentation_code LIKE '0205051I0BB%' это то, что я вижу:

              QUERY PLAN 
---------------------------------------------------------------------------------------------------------------------------- 
Seq Scan on vw_presentation_summary (cost=0.00..23202.16 rows=182 width=32) (actual time=0.440..222.383 rows=224 loops=1) 
    Filter: ((presentation_code)::text ~~ '0205051I0BB%'::text) 
    Rows Removed by Filter: 1115229 
    Buffers: shared hit=9259 
Planning time: 0.760 ms 
Execution time: 222.524 ms 
(6 rows) 

Объяснить ссылка: http://explain.depesz.com/s/nTL4

Почему это работает в Seq Scan не указательный поиск?

+0

http://www.postgresql.org/docs/9.4/static/indexes-opclass.html – zerkms

+0

Релевантно (я бы даже сказал дубликат): http://stackoverflow.com/q/27435980/251311 – zerkms

ответ

2

Оператор LIKE не может быть реализован с регулярным индексом, за исключением случаев использования «C», поэтому вы получаете последовательное сканирование по всем строкам. Что вам нужно, это varchar_pattern_ops index в вашей колонке «presentation_code». Таким образом, вы должны иметь индекс, как так:

CREATE INDEX "vw_idx_presentation_summary_vcops" 
    ON "vw_presentation_summary" (presentation_code varchar_pattern_ops); 

Вы также мог бы рассмотреть trigram index, хотя это не является абсолютно необходимым здесь.

+0

Спасибо! По какой-то причине я думал, что в моей базе данных используется языковой стандарт C, но при проверке это не так. – Richard

-1

Есть только две причины для базы данных, чтобы не использовать индекс:

  1. Он не может (индекс не имеет права)
  2. Он не хочет (оптимизатор оценивает, что полное сканирование будет быстрее)

Исправление: первоначально я думал, что это был случай # 2, но другой ответ объяснил, что это на самом деле # 1.

+0

На приблизительное 1.11 миллиона строк в таблице, ваше предложение невозможно. – Patrick

+0

oops, мой плохой. Я смотрел на «rows = 182», но это оценка размера вывода. Я пропустил часть «Rows Removed by Filter: 1115229». –

Смежные вопросы