У меня есть простая таблица person
со столбцом last_name
, в которую я добавил индекс GIST с
CREATE INDEX last_name_idx ON person USING gist (last_name gist_trgm_ops);
Согласно документам на https://www.postgresql.org/docs/10/pgtrgm.html, оператор <->
должен использовать этот индекс. Однако, когда я на самом деле пытаюсь использовать этот оператор разницы, используя этот запрос:
explain verbose select * from person where last_name <-> 'foobar' > 0.5;
Я получаю это обратно:
Seq Scan on public.person (cost=0.00..290.82 rows=4485 width=233)
Output: person_id, first_name, last_name
Filter: ((person.last_name <-> 'foobar'::text) < '0.5'::double precision)
И не похоже, что индекс используется. Однако, если я использую оператор %
с этой командой:
explain verbose select * from person where last_name % 'foobar';
Кажется, используется индекс:
Bitmap Heap Scan on public.person (cost=4.25..41.51 rows=13 width=233)
Output: person_id, first_name, last_name
Recheck Cond: (person.last_name % 'foobar'::text)
-> Bitmap Index Scan on last_name_idx (cost=0.00..4.25 rows=13 width=0)
Index Cond: (person.last_name % 'foobar'::text)
Я также заметил, что если я переместу оператор в выбранную часть запроса, индекс снова будет игнорироваться:
explain verbose select last_name % 'foobar' from person;
Seq Scan on public.person (cost=0.00..257.19 rows=13455 width=1)
Output: (last_name % 'foobar'::text)
Я упускаю что-то очевидное в том, как функция подобия использует индекс триграмм?
Я использую Postgres 10.5 на OSX.
РЕДАКТИРОВАТЬ 1
По предложению Лоренца я попытался установить enable_seqscan = off
, но, к сожалению, запрос с оператором <->
, похоже, по-прежнему игнорирует индекс.
show enable_seqscan;
enable_seqscan
----------------
off
explain verbose select * from person where last_name <-> 'foobar' < 0.5;
-----------------------------------------------------------------------------------------------------------------------------
Seq Scan on public.person (cost=10000000000.00..10000000290.83 rows=4485 width=233)
Output: person_id, first_name, last_name
Filter: ((person.last_name <-> 'foobar'::text) < '0.5'::double precision)