unaccent()
のIMMUTABLEバリアント
現在受け入れられている、誤った回答
の誤った情報を明確にするため :
式インデックスはIMMUTABLE
のみを許可します 関数(明らかな理由で)とunaccent()
STABLE
のみです 。コメントで提案した
tags->name
の内容によって異なります unaccent()
を追加すると便利な場合があります 式インデックスに、しかしそれはインデックスが使用されなかった理由の質問に直交しています:
実際の問題/解決策
演算子LIKE
クエリ内が微妙に間違っている (最も可能性が高い)。あなたはしません 'Weststrasse'を検索パターンとして解釈したい場合は、(正規化された)文字列をそのまま一致させたい。 =
に置き換えます 演算子を使用すると、現在のインデックスを使用した(ビットマップ)インデックススキャンが表示されます。関係なく unaccent()
の関数のボラティリティの :
SELECT * FROM germany.ways
WHERE lower(tags->'name') = lower(unaccent('unaccent','Weststrasse'))
なぜですか?
LIKE
の右オペランド パターンです 。 Postgresはパターンマッチングにプレーンなbtreeインデックスを使用できません(例外が適用されます
)。 LIKE
パターンとしてプレーン文字列(特殊文字なし)を使用すると、btreeインデックスの等価性チェックで最適化できます。ただし、文字列に特殊文字が含まれている場合は、これ インデックスが出ています。
IMMUTABLE
がある場合 LIKE
の右側にある関数 、それはすぐに評価することができ、前述の最適化はまだ可能です。 関数のボラティリティカテゴリに関するドキュメント
:
関数のボラティリティが低い場合(STABLE
)、同じことは不可能です。 またはVOLATILE
)。そのため、IMMUTABLE unaccent()
を偽造する「解決策」があります。 うまくいったようですが、実際には豚に口紅を塗っています。
繰り返しますが:
-
LIKE
を使用する場合 およびパターンについては、トリグラムインデックス<を使用してください。 / strong> 。 -
LIKE
を使用したくない場合 およびパターンについては、等式演算子=
を使用してください