Nous avons un simple, rejoindre déclaration dans laquelle certains des lorsque des clauses peut se transformer en est nulle. L'instruction est générée par une application. Un problème avec un plan de requête se pose lorsque nous avons cette est null contrainte.
Nous avons suivi l'approche décrite dans l'article sur StackExchange et créé un index composite pour les colonnes - nullable et celui auquel nous nous joignons. Cela aide seulement si nous sélectionnons seulement les colonnes indexées. Si nous sélectionnons des colonnes non indexées, elles sont ignorées, tandis que le résultat de la requête est le même - par exemple, aucune ligne n'est sélectionnée.
La seule option que nous voyons - pour changer la logique de l'application, mais peut-être il ya encore un moyen de résoudre ce problème au niveau de DB?indice composite est ignoré lors de la sélection des colonnes non indexées (Oracle)
--Illustrative sample. Prepare tables and indexes:
create table tableA
(
Acol1 varchar2(32) NOT NULL,
Acol2 varchar2(32),
Acol3 varchar2(32)
);
insert into tableA (Acol1, Acol2, Acol3)
values ('abcd1','abcd2A','abcd3A');
create table tableB
(
Bcol1 varchar2(32) NOT NULL,
Bcol2 varchar2 (32),
Bcol3 varchar2 (32)
);
insert into tableB (Bcol1, Bcol2, Bcol3)
values ('abcd1','abcd2B','abcd3B');
create index tableA_col12 on tableA (acol1, acol2);
create index tableB_col1 on tableB (Bcol1);
commit;
Ensuite, nous vérifions les plans:
1.
select a.Acol1 from tableA a join tableB b on a.Acol1 = b.Bcol1 where Acol2 is null;
--no rows selected
Plan1 - plage de balayage
2.
select * from tableA a join tableB b on a.Acol1 = b.Bcol1 where Acol2 is null;
--no rows selected
Plan2 (même lien ci-dessus) - Analyse de table complète
Quel serait le meilleur moyen d'améliorer les performances: modifier les requêtes, utiliser des index plus intelligents ou appliquer un plan fixe?
* Mise à jour * Alors que je préparais cette question, le plan de mon échantillon a changé par lui-même, maintenant nous avons Plan2* au lieu de Plan2 - pas de balayage de table complet. Toutefois, si je recréer l'échantillon (supprimer les tables et les préparer à nouveau), le plan est à nouveau Plan2 (analyse de table complète). Cette astuce ne se produit pas dans la base de données réelle.
Voici comment la vie est pour certaines bases de données, si vous sélectionnez des colonnes qui ne sont pas dans l'index, il n'utilisera pas l'index - vous pouvez simplement ajouter vos colonnes à l'index et le boost de vitesse. – Hogan
Vos tables sont minuscules. Le plan d'exécution dépend de la taille des données, donc sur de si petites quantités de données, cela n'a aucun sens. –
importer plus de données, appelez dbms_stats.gather_schema_stats (USER); et voir les changements ... quand vous avez un seul enregistrement le plus rapide, il suffit de charger la table en mémoire et de la scanner complètement – are