Oracle
 sql >> Base de données >  >> RDS >> Oracle

Oracle :profitez de l'utilisation de deux index

Vous dites que CAMPO47 est très sélectif. Mais vous filtrez uniquement sur IS NOT NULL. Ainsi, peu importe le nombre de valeurs distinctes dont il dispose, l'optimiseur ne l'utilisera pas comme point d'entrée.

Et à quel point est-il sélectif ? Comme vous pouvez le voir à partir des cardinalités dans le plan d'exécution, la sélection sur STATO='SC' trouve 12856 lignes dans votre table. 12702 de ces lignes ont évidemment CAMPO47 avec une valeur, donc seulement 154 lignes sont filtrées par le test de nullité. Si l'optimiseur avait opté pour l'index sur CAMPO47, combien de lignes cela aurait-il renvoyé ? Probablement beaucoup plus.

L'optimiseur ne peut utiliser qu'un seul index de tas pour accéder aux lignes d'une table. (Le mécanisme est différent pour les index bitmap lorsqu'ils appliquent une transformation en étoile). Donc, si vous pensez que les accès supplémentaires aux tables sont un fardeau insupportable, vous avez une option :un index composé. Si STATO est vraiment non sélectif (relativement peu de lignes), vous êtes probablement en sécurité en remplaçant l'index existant par un autre sur (STATO, CAMPO47).

Il existe une vieille astuce pour pousser la base de données à utiliser un index pour accéder aux opérations IS NOT NULL, et c'est d'utiliser un opérande qui ne peut être vrai que là où la colonne contient une valeur. Par exemple, quelque chose comme ça pour les colonnes de chaîne (je suppose que quelque chose appelé CAMPO47 doit juste être une chaîne) :

AND campo47 >= chr(0)

Cela correspondra à toute colonne contenant un ou plusieurs caractères ascii. Je ne sais pas si cela conduira à l'optimisation "à deux index" que vous décrivez, mais cela en vaut la peine. (Je testerais cela moi-même, mais je n'ai pas accès à une base de données Oracle pour le moment, et SQL Fiddle s'est lancé lorsque j'ai essayé de consulter le plan d'explication)