2016-02-09 2 views
3

С помощью этой таблицы:Почему Postgres не использует мой индекс gin?

=> \d "user" 
              Table "public.user" 
     Column  |   Type    |      Modifiers      
----------------------+-----------------------------+--------------------------------------------------- 
id     | integer      | not null default nextval('user_id_seq'::regclass) 
email    | character varying(255)  | 
Indexes: 
    "user_pkey" PRIMARY KEY, btree (id) 
    "user_email_key" UNIQUE CONSTRAINT, btree (email) 
    "user_email_idx" gin (email gin_trgm_ops) 

Этот запрос не использует индекс джин:

=> explain select email from "user" where email ilike '%j%'; 
          QUERY PLAN       
-------------------------------------------------------------- 
Seq Scan on "user" (cost=0.00..3986.42 rows=11886 width=22) 
    Filter: ((email)::text ~~* '%j%'::text) 
(2 rows) 

Почему?

ответ

0

https://hashrocket.com/blog/posts/exploring-postgres-gin-index

Предостережение Единственный недостатком этого подхода является то, что входной запрос должен быть по крайней мере 3 буквы, так как Postgres нужно будет, чтобы иметь возможность извлечь, по меньшей мере, один триграмму из входного запроса с целью используйте наш индекс триграмм.

+0

hah! вот и все. 'объяснять выбор электронной почты от пользователя, где адрес электронной почты ilike '% jjb%';' find 'Bitmap Heap Scan on "user" (cost = 28.02..49.45 rows = 11 width = 22) " –

+0

Фактически вход должен быть как' % abc% ''% ab' или 'a%', поэтому это не всегда три символа. –

0

Потому что вы на самом деле не используете индекс триграммы или свою версию postgres < 9.1.

select email from "user" where similarity(email, '[email protected]') > 0.5; 

где 0,5 ваш порог, 0-совершенно разные, 1-точное совпадение

UPD: Считают, что вы даете 1 символ в качестве сопоставления термина, потому что один символ может соответствовать множество документов, это может показаться плохой работой

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