2012-10-16 3 views
2

J'écris une vue qui utilise une colonne avec un index non UNIQUE dessus. Cependant, dans le contexte de ma vue, je suis confiant que la colonne ne contiendra que des valeurs uniques (en raison des conditions imposées dans la clause WHERE).Convaincre l'optimiseur SQL Oracle qu'une colonne indexée (bien que non-UNIQUE) contient réellement des valeurs uniques en pratique

Le véritable problème se produit lorsque quelqu'un interroge la vue basée sur cette colonne (par exemple SELECT * FROM MY_VIEW WHERE COLUMN_WITH_NON_UNIQUE_INDEX = 'foo'). L'optimiseur est convaincu qu'il recevra beaucoup de lignes (parce que l'index n'est pas techniquement UNIQUE). À cause de cela, l'optimiseur évite d'utiliser d'autres index ailleurs dans la vue en faveur des analyses de table complètes (pas cool).

Existe-t-il un moyen de convaincre l'optimiseur qu'une colonne avec un index non UNIQUE contiendra, en fait, des valeurs uniques? Bien sûr, il est possible que des valeurs dupliquées puissent se frayer un chemin dans la colonne, mais cela serait considéré comme un bug et ne devrait pas faire souffrir les données légitimes et uniques.

Malheureusement, je ne suis pas en contrôle de la table en question (soupir).

+0

Vos statistiques sont-elles à jour? Il devrait déjà utiliser l'index approprié si elles le sont et il est en effet avantageux. – Mat

+0

Des index uniques/contraintes uniques indiquent à l'optimiseur ce que vous voulez lui dire. Pourquoi vous attendez-vous à ce qu'il y ait encore une autre façon de faire cela? – MatBailie

+0

@Mat: Les statistiques étaient périmées alors j'ai rassemblé des statistiques sur la table. Il a amélioré certaines parties du plan d'explication, mais pas cette partie particulière. Je vais continuer à enquêter. –

Répondre

2

Oracle vous permet de créer des visuels uniques contraintes (et clé primaire) sur les vues qui ne sont pas appliquées, mais qui fournissent l'optimiseur exactement ce genre d'information

ALTER VIEW your_view_name 
    ADD CONSTRAINT name_of_constraint UNIQUE(column_with_non_unique_index) 
    RELY DISABLE NOVALIDATE; 

Cela dira Oracle qu'il peut compter sur le fait que les données sont uniques mais qu'il n'a pas besoin de valider la contrainte. L'optimiseur pourra cependant utiliser les métadonnées supplémentaires fournies par la contrainte.

1

Vous pouvez essayer ce qui suit:

recueillir des statistiques sur la table avec DBMS_STATS avec METHOD_OPT fixé POUR TOUS LES COLONNES TAILLE AUTO Avec ce paramètre, Oracle détermine automatiquement les colonnes nécessitent histogrammes et le nombre de godets (taille) de chaque histogramme. Vous pouvez également spécifier manuellement quelles colonnes doivent avoir des histogrammes et la taille de chaque histogramme.

dbms_stats.gather_table_stats(
ownname => 'schemaname' , 
tabname => 'tablename' , 
estimate_percent => 100 , 
method_opt => 'for all indexed columns size auto' , 
cascade => true); 
Questions connexes