Optimisation des performances PL / SQL pour les requêtes génériques LIKE '% ...%'
Nous utilisons la base de données Oracle 11g.
Comme vous pouvez ou ne pouvez pas savoir, si vous utilisez les caractères génériques de la requête avec "%" en avant de la chaîne, la colonne index n'est pas utilisé et un full table scan qui se passe.
Il semble comme il n'y a pas de manière définitive à une suggestion sur la façon d'améliorer ce type de requête, mais vous pouvez peut-être partager quelques précieuses informations à partir de votre expérience sur la manière d'optimiser la requête suivante:
SELECT *
FROM myTable
WHERE UPPER(CustomerName) like '%ABC%'
OR UPPER(IndemnifierOneName) like '%ABC%'
OR UPPER(IndemnifierTwoName) like '%ABC%';
...où tous les 3 colonnes sont de type varchar2(100) et ABC est une valeur de la variable paramètre d'entrée.
@Tous ce qui suggère CONTEX index, veuillez noter mes données est mise à jour à tout moment de la journée tous les jours et cet indice nécessite la re-synchronisation, c'est pas une bonne option pour une table de de 1,5 million de lignesdésolé.
P. S. je vais upvote chaque réponse, donc s'il vous plaît garder à venir.
source d'informationauteur Tsar
Vous devez vous connecter pour publier un commentaire.
Comme déjà mentionné, vous pourriez ajouter un ctx contexte de l'index pour le nom des colonnes.
en supposant un petit nombre d'enregistrements mis à jour, 1 option est d'actualiser votre index au quotidien. (et d'enregistrer quand c'est arrivé)
puis ajouter un lastupdate colonne date & index de votre table de recherche en cours.
Il devrait être possible de scanner votre ctx indice pour la majorité de la vieille données inchangées
sélectionnez-le et sélectionnez le faible pourcentage de mise à jour des données à l'aide de la traditionnelle COMME
e.g:
REMARQUE: vous pouvez trouver votre plan de requête va un peu mentale (beaucoup de bitmap conversions à l'id de ligne) dans ce cas, diviser les 2 parties de la OU dans une UNION de TOUTES les requêtes.
e.g
La seule optimisation est de ne pas utiliser ce type de requête et au lieu d'utiliser les fonctionnalités natives de la plateforme de base de données:
Voir Oracle Texte: http://www.oracle.com/technetwork/database/enterprise-edition/index-098492.html
La réponse commune pour SQL Server questions seraient de Recherche en Texte Intégral.. agréable de voir l'Oracle a quelque chose d'aussi bon ou meilleur.
La
UPPER()
est en train de tuer votre index avant toute chose, pensez à utiliser une regexp. La première%
peut éviter un indice normal scan, mais pas toujours les résultats dans une Table Pleine d'Analyse, mais dans un Index Complet de Numérisation, qui est plus rapide que la FTS.Je suppose que
'ABC'
est variable. Si non, une fonction de l'indice est le chemin à parcourir.Parfois ce genre de requête est inévitable -- extraction de domaine à partir d'une URL, ou peut-être la racine d'un mot avec un préfixe et d'un suffixe.
Vous pouvez recourir à un index de texte intégral avec ou sans personnalisé générateur de jetons.
Ou si les chaînes que vous êtes à la recherche pour sont en nombre fini et connu à l'avance (par exemple, vous travaillez avec un ensemble limité de noms de domaine qui doivent être extraites à partir d'une URL), vous pouvez utiliser une fonction déterministe qui peut être indexée.
http://www.akadia.com/services/ora_function_based_index_2.html
Utiliser Oracle texte, MAIS légèrement plus récente CTXCAT variation - ce nom de domaine index est mis à jour dans le cadre de la transaction, que les insertions, mises à jour de la ligne en question et il est donc toujours à jour - Voir Oracle Oracle Texte de la documentation pour plus de détails.