2017-10-18 5 views
-1

J'ai un wich de requête ressemble:modèle Postgresql performances correspondant à

SELECT * 
FROM my_table 
WHERE 'some_string' LIKE mytable.some_column || '%%' 

Comment puis-je mon index some_column colonne pour améliorer cette performance de requête? Ou est-ce une meilleure façon de filtrer cela?

+0

S'il vous plaît confirmer: ' 'some_string' LIKE mytable.some_column || '%' ', pas' mytable.some_column LIKE 'une_chaîne%' '? Si oui, combien de temps vos chaînes peuvent-elles être (min/moy/max)? Combien de lignes dans la table, combien de chaînes distinctes? En outre: Votre version de Postgres et la définition de table montrant le type de données et les contraintes pour les colonnes pertinentes et les index associés que vous avez. –

Répondre

1

Ce prédicat recherche efficace pour tous les préfixes pour une chaîne donnée:

WHERE 'some_string' LIKE mytable.some_column || '%' 

Peut-être % est un caractère spécial dans votre client, qui doit être échappé avec un autre % pour passer un % littéral, sinon '%%' serait être juste du bruit et peut être remplacé par '%'.

La solution la plus efficace devrait être un CTE récursive (ou similaire) qui correspond à chaque préfixe exactement, en commençant par some_column = left('some_string', 1), jusqu'à some_column = left('some_string', length('some_string')) (= 'some_string').

Vous n'avez besoin que d'un simple index btree sur la colonne pour cela. Selon les détails de l'implémentation, les index d'expression partielle peut améliorer les performances ...

connexes:

+0

Je peux fournir le rCTE, mais d'abord clarifier votre question, s'il vous plaît. –

+0

Merci, je pense que j'ai assez pour savoir comment résoudre ce problème.Il semble que c'est un problème commun. – Egg

0

Je crois que vous avez l'intention d'écrire la requête suivante:

SELECT * 
FROM my_table 
WHERE mytable.some_column LIKE 'some_string%'; 

En d'autres termes, vous voulez trouver des enregistrements où une colonne commence par some_string suivi de quoi que ce soit, peut-être rien du tout. Pour autant que je sache, un index B-tree classique sur some_column sera efficace, dans une certaine mesure, dans votre requête. La raison en est que Postgres peut traverser l'arbre à la recherche du préfixe some_string. Une fois qu'il a trouvé cette entrée, au-delà, l'index pourrait ne pas aider. Mais un indice sur some_column devrait vous donner quelques avantages de performance ici.

Une condition où un indice ne pas aide serait la suivante:

WHERE mutable.some_column LIKE '%some_string'; 

Dans ce cas, l'indice est rendu la plupart du temps inutile, parce que nous avons aucune idée avec ce préfixe la valeur de colonne doit commencer .

+0

Vous avez cru faux. – Egg

+0

@Egg Quel est le problème avec ma réponse? –