Comment utiliser une fonction de base de l'index sur une colonne contenant des valeurs Null dans Oracle 10+?
Permet simplement de dire que vous avez une table Oracle:
CREATE TABLE person (
id NUMBER PRIMARY KEY,
given_names VARCHAR2(50),
surname VARCHAR2(50)
);
avec fonction de ces indices:
CREATE INDEX idx_person_upper_given_names ON person (UPPER(given_names));
CREATE INDEX idx_person_upper_last_name ON person (UPPER(last_name));
Maintenant, given_names a pas de valeurs NULL, mais pour la commodité du raisonnement nom ne. Si je fais ceci:
SELECT * FROM person WHERE UPPER(given_names) LIKE 'P%'
l'expliquer plan me raconte son à l'aide de l'index, mais le modifier:
SELECT * FROM person WHERE UPPER(last_name) LIKE 'P%'
il ne le fait pas. L'Oracle docs disent que l'utilisation de la fonction d'index de base ne sera utilisé que lorsque plusieurs conditions sont remplies, un est de s'assurer il n'y a pas de valeurs NULL, car ils ne sont pas indexés.
J'ai essayé ces requêtes:
SELECT * FROM person WHERE UPPER(last_name) LIKE 'P%' AND UPPER(last_name) IS NOT NULL
et
SELECT * FROM person WHERE UPPER(last_name) LIKE 'P%' AND last_name IS NOT NULL
Dans ce dernier cas, j'ai même ajouté un index sur le nom, mais peu importe ce que j'essaie il utilise un full table scan. En supposant que je ne peut pas se débarrasser de l de valeurs NULL, comment puis-je obtenir cette requête à utiliser l'index sur la partie SUPÉRIEURE(nom)?
OriginalL'auteur cletus | 2008-10-07
Vous devez vous connecter pour publier un commentaire.
L'index peut être utilisé, si l'optimiseur peut-être choisi de ne pas l'utiliser pour votre exemple particulier:
La documentation que vous avez lu, c'était sans doute de souligner que, comme tout autre indice, tout-clés null ne sont pas stockées dans l'index.
OriginalL'auteur Tony Andrews
Dans votre exemple, vous avez créé le même index à deux reprises, ce qui donne une erreur donc je suppose que c'était une erreur dans le collage, et non le code que vous avez essayé.
Je l'ai essayé avec
et produits attendus du plan de requête:
Pour répondre à votre question, oui, ça devrait fonctionner. Essayez de double-vérifier que vous avez le deuxième indice créé correctement.
Également faire une allusion explicite:
Si cela fonctionne, mais seulement avec l'indice, alors il est probablement liée à CBO statistiques mal tourné, ou CBO liées initialisation des paramètres.
OriginalL'auteur CaptainPicard
Êtes-vous sûr que vous voulez l'indice à utiliser? Complète les analyses de la table ne sont pas mauvais. En fonction de la taille de la table, il pourrait être plus efficace de faire une analyse de la table que d'utiliser un index. Elle dépend aussi de la densité et de la distribution des données, qui est pourquoi les statistiques sont recueillies. Le coût de l'optimiseur peut généralement faire confiance pour faire le bon choix. Sauf si vous avez une problème de performances, je ne m'inquiéterais pas trop à ce sujet.
OriginalL'auteur
Oracle continuera d'utiliser une fonction d'index avec des colonnes qui contiennent la valeur null - je pense que vous avez mal interprété la documentation.
Vous avez besoin de mettre une nvl dans la fonction d'index si vous voulez vérifier ce que.
Quelque chose comme...
Vous pouvez ensuite la requête à l'aide de l'index avec
Bien que, tous un peu moche. Comme la plupart des gens ont des noms de famille, peut-être un "not null" est le cas :-).
OriginalL'auteur Nick Pierpoint
Vous pouvez contourner le problème des valeurs null être indexée dans ce ou d'autres situations également l'indexation basée sur une valeur littérale:
Cela vous permet d'utiliser l'index pour de telles questions comme:
Cette requête ne serait pas normalement etats-unis d'un index, à l'exception de la bitmap d'index ou index dont un n'acceptant pas cette valeur réelle de la colonne autre que le nom de famille.
Toute requête utilisée limite SUPÉRIEURE(nom de famille). David truc du assure que les valeurs nulles de la tige(nom de famille) sont indexés. Oracle n'a pas d'index si toutes les valeurs sont nulles. La valeur littérale de 0 assure que cela n'arrive jamais.
OriginalL'auteur David Aldridge