Я хочу получить способ с заданным именем из базы данных OpenStreetMap, импортированной в PostgreSQL 9.3.5, ОС - это 64-разрядная версия Win7. Для того, чтобы быть терпимым к отказу, я использую незаметное расширение Postgres.
Мой запрос выглядит следующим образом:
SELECT * FROM germany.ways
WHERE lower(tags->'name') like lower(unaccent('unaccent','Weststrasse'))
План запроса:
Seq Scan on ways (cost=0.00..2958579.31 rows=122 width=465)
Filter: (lower((tags -> 'name'::text)) ~~ lower(unaccent('unaccent'::regdictionary, 'Weststrasse'::text)))
Странно то, что этот запрос использует последовательное сканирование на пути, хотя индекс присутствует в lower(tags->'name')
:
CREATE INDEX ways_tags_name ON germany.ways (lower(tags -> 'name'));
Postgres использует индекс, как только я удаляю unaccent из запроса:
SELECT * FROM germany.ways
WHERE lower(tags->'name') like lower('Weststrasse')
План запроса:
Index Scan using ways_tags_name on ways (cost=0.57..495.43 rows=122 width=465)
Index Cond: (lower((tags -> 'name'::text)) = 'weststrasse'::text)
Filter: (lower((tags -> 'name'::text)) ~~ 'weststrasse'::text)
Почему unaccent предотвращает использование Postgres индекса? По-моему, это не имеет смысла, потому что результат незатухающего (удаление диакритики и т.д.) Должен быть полностью известен до того, как будет выполнен фактический запрос. Поэтому Postgres должен иметь возможность использовать индекс. Как избежать seq-сканирования при использовании unaccent?