sql >> データベース >  >> RDS >> PostgreSQL

unaccent()はPostgresでのインデックスの使用を防ぎます

    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()を偽造する「解決策」があります。 うまくいったようですが、実際には豚に口紅を塗っています。

    繰り返しますが:




    1. 遅延セグメント作成機能が有効になっていません(ORA-00439)

    2. 初めてユーザー権限を付与したときにGRANTUSAGEが作成されるのはなぜですか?

    3. 権限を持つ役割を削除する

    4. EBSR12用のDMZを作成する方法