C'est comme si vous lisiez ailleurs dans jjanes :un index d'expression n'est pris en compte que si l'expression correspond exactement au prédicat de la requête. Le planificateur de requêtes Postgres n'est pas une IA. Cela irait rapidement à l'encontre de l'objectif d'accélérer les requêtes si leur planification prend trop de temps.
Vous pouvez optimiser un peu votre index, si cela peut vous consoler. left()
est plus simple et plus rapide que substring()
:
CREATE INDEX record_changes_log_detail_old_value_ix_btree
ON record_changes_log_detail (left(old_value,1024) text_pattern_ops);
En outre, il existe une taille de ligne maximale de 2 704 octets pour les index btree, pas une "limite de 2172 caractères sur les arbres B" .
Plus important encore, pour les vérifications d'égalité uniquement, comme le suggère votre question, un index btree sur une valeur de hachage utilisant md5(old_value)
ou hashtext(old_value)
serait beaucoup plus efficace. Si vous le faites, n'oubliez pas de vous défendre contre les collisions de hachage comme ça :
SELECT *
FROM record_changes_log_detail
WHERE hashtext(old_value) = hashtext('Gold Kerrison Neuro')
AND old_value = 'Gold Kerrison Neuro';
Le premier prédicat vous donne un accès rapide à l'index. Le second exclut les faux positifs. Les collisions devraient être extrêmement rares. Mais possible. Et la possibilité grandit avec la taille de la table.
Connexe :
- La requête SELECT avec DISTINCT sur une structure de table pour les graphiques est très lente
- Quel est le type de données optimal pour un champ MD5 ?
- Recherche en texte intégral dans CouchDB
Ou un index de hachage comme celui que vous avez déjà envisagé :
- Pourquoi un index de hachage Postgres 11 est-il si volumineux ?
(Ici, vous n'avez pas à vous soucier des collisions de hachage ; elles sont gérées en interne.)