PostgreSQL 9.3.5 にインポートされた OpenStreetMap データベースから特定の名前のウェイを取得したいのですが、OS は Win7 64 ビットです。ある程度の耐障害性を持たせるために、Postgres の unaccent 拡張機能を使用しています。
私のクエリは次のようになります。
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 によるインデックスの使用を妨げているのはなぜですか? 私の意見では、これは意味がありません。実際のクエリが実行される前に、unaccent (分音符号の削除など) の結果が完全にわかっているはずだからです。したがって、Postgres はインデックスを使用できるはずです。unaccent を使用する場合、どのように seq スキャンを回避できますか?