web-dev-qa-db-ja.com

なぜテキスト列のtext_pattern_opsにインデックスを付けるのですか?

今日 7週間で7つのデータベース は、オペレーターごとのインデックスを紹介しました。

値が小文字でイ​​ンデックス付けされている限り、text_pattern_ops演算子クラスインデックスを作成することにより、前のクエリとパターンマッチングする文字列にインデックスを付けることができます。

CREATE INDEX moves_title_pattern ON movies (
    (lower(title) text_pattern_ops);

タイトルはテキストタイプであるため、text_pattern_opsを使用しました。 varchar、char、または名前にインデックスを付ける必要がある場合は、関連する演算(varchar_pattern_opsbpchar_pattern_ops、およびname_pattern_ops)を使用します。

この例は本当に混乱します。なぜこれが役立つのですか?

列がテキストタイプの場合、他のタイプ(varchar、char、name)は、検索値として使用される前にテキストにキャストされませんか?

そのインデックスは、デフォルトの演算子を使用したインデックスとどのように異なるのですか?

CREATE INDEX moves_title_pattern ON movies (lower(title));

ドキュメントには、このような質問に対する回答が含まれていることがよくあります。 この場合 のようにも:

演算子クラスtext_pattern_ops、varchar_pattern_ops、およびbpchar_pattern_opsは、タイプtext、varchar、charのBツリーインデックスをそれぞれサポートします。デフォルトの演算子クラスとの違いは、値がロケール固有の照合規則に従ってではなく、文字ごとに厳密に比較されることです。これにより、これらの演算子クラスは、データベースが標準の「C」を使用しない場合に、パターンマッチング式(LIKEまたはPOSIX正規表現)を含むクエリでの使用に適しています。ロケール。例として、次のようにvarchar列にインデックスを付けることができます。

CREATE INDEX test_index ON test_table (col varchar_pattern_ops);

通常の<、<=、>、または> =の比較を含むクエリでインデックスを使用する場合は、デフォルトの演算子クラスでインデックスを作成する必要があることに注意してください。このようなクエリでは、xxx_pattern_ops演算子クラスを使用できません。 (ただし、通常の等値比較ではこれらの演算子クラスを使用できます。)異なる演算子クラスを使用して、同じ列に複数のインデックスを作成することが可能です。

ドキュメントは続けて言う:

Cロケールを使用する場合は、xxx_pattern_ops演算子クラスは必要ありません。これは、デフォルトの演算子クラスのインデックスがCロケールでのパターンマッチングクエリに使用できるためです。

ロケールは次のように確認できます(「C」ではなくUTF8である可能性があります)。

postgres=> show lc_collate;
 lc_collate
-------------
 en_GB.UTF-8
21
dezso