Pourquoi voudriez-vous indexer text_pattern_ops sur une colonne de texte?

18

Aujourd'hui, sept bases de données en sept semaines m'ont présenté les index par opérateur.

Vous pouvez indexer des chaînes pour le modèle correspondant aux requêtes précédentes en créant un text_pattern_opsindex de classe d'opérateur, tant que les valeurs sont indexées en minuscules.

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

Nous avons utilisé le text_pattern_opscar le titre est de type texte. Si vous avez besoin d'indexer Varchars, caractères, ou les noms, utilisez les opérations connexes: varchar_pattern_ops, bpchar_pattern_opset name_pattern_ops.

Je trouve l'exemple vraiment déroutant. Pourquoi est-il utile de faire cela?

Si la colonne est de type texte, les autres types (varchar, char, name) ne seraient-ils pas convertis en texte avant d'être utilisés comme valeur de recherche?

Comment cet index se comporte-t-il différemment de celui utilisant l'opérateur par défaut?

CREATE INDEX moves_title_pattern ON movies (lower(title));
Iain Samuel McLean Elder
la source
1
Cette question connexe peut être utile: dba.stackexchange.com/questions/10694/…
Erwin Brandstetter
Merci, Erwin. Votre réponse à cette question a été très utile lors de la recherche des idées dans le livre.
Iain Samuel McLean Elder

Réponses:

20

La documentation vous donne souvent une réponse à ces questions. Comme dans ce cas aussi:

Les classes d'opérateur text_pattern_ops, varchar_pattern_ops et bpchar_pattern_ops prennent en charge les index B-tree sur les types text, varchar et char respectivement. La différence avec les classes d'opérateurs par défaut est que les valeurs sont comparées strictement caractère par caractère plutôt qu'en fonction des règles de classement spécifiques aux paramètres régionaux. Cela rend ces classes d'opérateurs utilisables par les requêtes impliquant des expressions de correspondance de modèle (expressions régulières LIKE ou POSIX) lorsque la base de données n'utilise pas les paramètres régionaux "C" standard. Par exemple, vous pouvez indexer une colonne varchar comme ceci:

CREATE INDEX test_index ON test_table (col varchar_pattern_ops);

Notez que vous devez également créer un index avec la classe d'opérateur par défaut si vous souhaitez que les requêtes impliquant des comparaisons <, <=,> ou> = ordinaires utilisent un index. Ces requêtes ne peuvent pas utiliser les classes d'opérateur xxx_pattern_ops . (Les comparaisons d'égalité ordinaires peuvent cependant utiliser ces classes d'opérateurs.) Il est possible de créer plusieurs index sur la même colonne avec différentes classes d'opérateurs.

La documentation poursuit en disant:

Si vous utilisez les paramètres régionaux C, vous n'avez pas besoin des classes d'opérateur xxx_pattern_ops, car un index avec la classe d'opérateur par défaut est utilisable pour les requêtes de correspondance de modèle dans les paramètres régionaux C.

Vous pouvez vérifier vos paramètres régionaux comme suit (il s'agit probablement d'UTF8 plutôt que de "C"):

postgres=> show lc_collate;
 lc_collate
-------------
 en_GB.UTF-8
dezso
la source
Ah! J'ai lu cela, mais j'ai trouvé difficile à suivre, donc je ne l'ai pas compris. Diriez-vous que l'utilité de text_pattern_opsdépend de la localisation? Il semble que cela me serait bénéfique car mon environnement local est 'en_US.UTF-8' (pas 'C'), donc les requêtes de modèle ne peuvent pas utiliser l'index par défaut.
Iain Samuel McLean Elder
Exactement. J'ajouterais (mais ce ne sont que des spéculations) qu'avec les données restant à l'intérieur des caractères ASCII de base, la classe d'opérateur par défaut est tout aussi bonne - au moins je vois des requêtes avec LIKE 'quelque chose%' utilisant de tels index.
dezso
5
@dezso: Si vous avez vu une LIKErequête utilisant un index b-tree simple, la base de données doit utiliser les Cparamètres régionaux. Ou l'index est défini avec le COLLATE "POSIX"(ou COLLATE "C") et la requête spécifie une correspondance COLLATION. Avec tout autre classement, l'ordre de l'index ne correspond pas aux règles de paramètres régionaux et ne peut donc pas être utilisé pour la correspondance de modèles.
Erwin Brandstetter
1
@ErwinBrandstetter Je dois confirmer, vous avez raison.
dezso
1
@StopHarmingMonica vous obtenez la bonne réponse (et aucune erreur), juste la requête sera peut-être plus lente, ne pouvant pas utiliser l'index.
dezso