J'ai rencontré cette question lors d'une interview et je ne savais pas comment répondre:
Il y a une table qui a un index sur une colonne, et vous interrogez:
select * from table_name where column_having_index="some value";
La requête prend trop de temps et vous découvrez que l'index n'est pas utilisé. Si vous pensez que les performances de la requête seront meilleures en utilisant l'index, comment pourriez-vous forcer la requête à utiliser l'index?
Vous pouvez utiliser des conseils d'optimisation
select /*+ INDEX(table_name index_name) */ from table
etc ...
En savoir plus sur l'utilisation des conseils d'optimisation: http://download.Oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm
Il pourrait y avoir plusieurs raisons pour que l'index ne soit pas utilisé. Même après que vous spécifiez des conseils, il y a des chances que l'optimiseur Oracle pense le contraire et décidez de ne pas pour utiliser Index . Vous devez parcourir la partie EXPLAIN PLAN et voir quel est le coût de l'instruction avec INDEX et sans INDEX.
En supposant que Oracle utilise CBO . Le plus souvent, si l'optimiseur pense que le coût est élevé avec INDEX, même si vous le spécifiez dans les conseils, l'optimiseur ignorera et continuera pour l'analyse complète de la table. Votre première action devrait être de vérifier DBA_INDEXES pour savoir quand les statistiques sont LAST_ANALYZED. S'il n'est pas analysé, vous pouvez définir la table, l'index à analyser .
begin
DBMS_STATS.GATHER_INDEX_STATS ( OWNNAME=>user
, INDNAME=>IndexName);
end;
Pour table.
begin
DBMS_STATS.GATHER_TABLE_STATS ( OWNNAME=>user
, TABNAME=>TableName);
end;
Dans les cas extrêmes, vous pouvez essayer configurer les statistiques par vous-même.
Si vous pensez que les performances de la requête seront meilleures en utilisant l'index, comment pourriez-vous forcer la requête à utiliser l'index?
D'abord, vous vérifieriez bien sûr que l'indice a donné un meilleur résultat pour renvoyer l'ensemble de données complet, non?
L'indice d'index est la clé ici, mais la façon la plus à jour de le spécifier est avec la méthode de dénomination des colonnes plutôt qu'avec la méthode de dénomination des index. Dans votre cas, vous utiliseriez:
select /*+ index(table_name (column_having_index)) */ *
from table_name
where column_having_index="some value";
Dans des cas plus complexes, vous pourriez ...
select /*+ index(t (t.column_having_index)) */ *
from my_owner.table_name t,
...
where t.column_having_index="some value";
En ce qui concerne les index composites, je ne suis pas sûr que vous ayez besoin de spécifier toutes les colonnes, mais cela semble être une bonne idée. Voir les documents ici http://docs.Oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#autoId18 sur plusieurs index_specs et utilisation de index_combine pour plusieurs index, et ici - http://docs.Oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#BABGFHCH pour la spécification de plusieurs colonnes dans l'index_spec.
Il existe un index approprié sur column_having_index, et son utilisation augmente en fait les performances, mais Oracle ne l'a pas utilisé ...
Vous devez collecter des statistiques sur votre table pour permettre à l'optimiseur de voir que l'accès aux index peut vous aider. L'utilisation d'un indice direct n'est pas une bonne pratique.