Oracle9i : pb perf : like avec variable

Oracle9i : pb perf : like avec variable - SQL/NoSQL - Programmation

Marsh Posté le 13-03-2006 à 22:42:56    

Bonjour,  
j'ai un problème de perf sur une de mes requêtes, en particulier sur une whereclause like !  
 
J'ai 2 tables :  
- table client (codeclient varchar2(20), autrecols varchar2(10)) avec un index sur la colonne codeclient. Cette table contient environ 800k lignes  
- table parametre (param varchar2(512))  
 
Le fonctionnement de mon outil est le suivant :  
- un ensemble de requête sont prédéfinies dans le code  
- l'utilisateur saisie des paramètres d'entrée (ca peut etre des chaines caractères, des nombres, ... d'où le varchar2 à 512)  
- ces paramètres sont chargés dans la table parametre  
- la requête prédéfinie va faire ensuite des select dans les tables qui vont bien  
 
Le pb, c'est que l'utilisateur a besoin de mettre des caractères joker (%). Ainsi, il peut rentrer un paramètre DUP% ... ca ira dans ma table client, et retournera DUPONT, DUPOND, DUPOUET, DUPMACHIN ...  
 
Alors, autant la requête :  
select c.* from client c where c.codeclient like 'DUP%'; est instantanée (car elle utilise l'index).  
Autre la requête :  
select c.* from client c,parametre p where c.codeclient like p.param; est super long; car n'utilise pas l'index, ... et la cardinalité explose.  
 
J'ai vu que sur interbase, il y a une commande "starting by" qui est un truc qui ressemble au like avec un % à la fin (donc permettant l'utilisation de l'index). Mais en oracle 9i (là ou je suis), il n'y a pas d'équivalent.  
 
Existe-t-il un moyen de forcer l'index par hint ?!?  
 
Merci !!!

Reply

Marsh Posté le 13-03-2006 à 22:42:56   

Reply

Marsh Posté le 14-03-2006 à 10:43:56    

J'ai peut être une piste, j'ai eu un problème du même genre mais sur Oracle 8.
Un espèce de bug de l'interpréteur de requête d'Oracle.
Le problème venait du fait que le champ de la table était du varchar et que ma requête n'explicitait pas le type derrière la comparaison du critère.
Moi c'était un integer sous forme de chaine de caractères, du coup en rajoutant les ', j'ai réussi à forcer l'utilisation de l'index.
Enfin bref l'interpréteur de requêtes n'est pas facile à comprendre.
j'ai même aussi constaté un espèce critère de longueur, si l'integer avait moins de 2 chiffres ca marchait bien, c'est quand ca dépassait 3 chiffres que l'index n'était pas pris en compte.
Donc dans ton cas, à mon avis le problème vient du fait que tu as au niveau de ta comparaison un varchar(20) et de l'autre un varchar(512), du coup l'interpréteur de requêtes n'arrive pas ou ne se décide pas à appliquer l'indexation.
Tu devrais essayer de convertir ton varchar(512) en varchar(20).
Au pire, si ca marche pas, tu fait 2 requêtes, 1 pour lire le p.param et l'autre pour ta requête principale.

Reply

Marsh Posté le 14-03-2006 à 19:03:28    

effectivement tu peux forcer l'utilisation d'un index par un hint comme suit :
 
select /*+ INDEX(Tatable(ou l'alias de ta table), TonIndex) */ c.*  
from ....
 
par ailleur je te conseillerai de voir pourquoi il n'utilise pas l'index, est ce que tu utilises les stats oracle sur la table, si oui, est ce que tu utilise la commande ANALYZE ou DBMS_STAT... Parfois on ajoutant des stats on peut passer de minute à milliseconde ...
 
Abdel

Reply

Marsh Posté le 15-03-2006 à 21:33:00    

j'ai réussi à m'en sortir en mettant un hint +RULE !!!!
Ce qui est rigolo, c'est que j'ai plusieurs requêtes du meme type, mais que le comportement est completement différent à chaque fois. Merci en tout cas

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed