2015-11-09 1 views
1

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.

+1

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

+5

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. –

+0

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

Répondre

0

Mon commentaire était un peu désinvolte alors je vais essayer de vous donner plus de détails. Voici quelques conseils généraux pour obtenir un meilleur à optimiser les systèmes SQL et des requêtes spécifiques

  • tout d'abord @GordonLinoff est juste (comme toujours) vous n'obtiendrez quelque chose de significatif sur une petite table. L'optimiseur sait et fonctionnera différemment.

  • deuxième fois que vous avez une table de bonne taille (au moins 50k lignes en fonction de votre mémoire), vous devez vous assurer que vous exécutez des statistiques sur les tables ou vous l'optimiseur (et les index) ne va pas fonctionner

  • Troisièmement, vous devez utiliser les outils, apprendre à comprendre un plan d'exécution - vous ne pouvez pas obtenir mieux à ces techniques sans avoir une compréhension profonde de ce que le système vous dit. Les bases de données sql modernes ont des outils qui vont regarder une requête et suggérer des index - utilisez-les, tout comme le plan d'exécution que vous pouvez apprendre beaucoup. Rappelez-vous, ces outils ne sont pas infaillibles, vous devez essayer les suggestions et voir si elles fonctionnent.

  • Enfin, lisez beaucoup. Une source que je pense est particulièrement intéressant est l'utilisateur stackoverflow Quassnoi qui a un blog à explainextended. Bien que n'étant pas aussi actif récemment, ce blog (et beaucoup de ses réponses) sont assez éclairant, je m'attends à ce que vous les apprécierez. Il y a beaucoup de blogs et de livres sur le sujet et chaque élément aide.

Dans ce cas, pour votre plus grande table, je pense (et cela a la mise en garde il y a beaucoup de choses sur votre base de données et modèle de données, je ne sais pas) simplement l'ajout de colonnes à l'index travailleront - - mais utilisez l'outil Oracle et voyez ce qu'il suggère. Essayez cela en premier.

+0

Un autre bon site pour comprendre le fonctionnement des index est: http://use-the-index-luke.com/ –