8

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 スキャンを回避できますか?

4

1 に答える 1