Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 08/09/2011, 15h28   #1
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Par défaut Optimisation : Utilité de rappeler les derniers champs d'une clé composite ?

Bonjour,

Je suis chez un client, et je fait des évolutions dans des vues.
J'en profite pour remettre de l'ordre aussi, et virer les lourdeurs de conceptions des requêtes.

J'ai une table dont voici la structure :

matable (id1, id2, id3, id4, val1, val2, val3, ...)

En souligné la clé composite de la table.

Chez ce client, le paramétrage (immuable pour cette partie applicative) fait que id1 et id2 sont suffisants pour identifier une ligne. id3 et id4 sont toujours à 0, quelles que soient les valeurs de id1 et id2.

La requête est donc écrite avec une jointure sur la table qui ne teste que id1 et id2.
=> Il en résulte dans le plan d'exécution un RANGE SCAN de l'index unique.

Est-ce réellement intéressant de rajouter dans la jointure "id3 = 0 and id4 = 0" afin d'expliquer à Oracle qu'on cherche une unique ligne dans la jointure ?

C'est ce que j'ai fais (pour le fun, au cas où un jour, le paramétrage immuable ne change), mais je me pose la question...

A l'exécution je n'ai pas de différence perceptible.
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2011, 16h42   #2
Membre confirmé
 
Avatar de LBO72
 
Inscription : mai 2007
Messages : 385
Détails du profil
Informations personnelles :
Âge : 43
Localisation : France

Informations forums :
Inscription : mai 2007
Messages : 385
Points : 282
Points : 282
Bonjour,

As-tu modifié ton index pour qu'il ne porte plus que sur id1 et id2 ?

Cdlt,
LBO72.
LBO72 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/09/2011, 17h56   #3
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
Non, ça c'est pas possible.

Il s'agit d'un ERP, donc je ne peux pas modifier ni le modèle des données, ni les index standard.

Du coup je dois trouver la solution la plus performante en conservant cette structure.

De plus, la table sert à plusieurs choses, et d'autres entités utilisent la totalité de la clé.
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2011, 11h02   #4
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 926
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 926
Points : 4 547
Points : 4 547
Citation:
Envoyé par StringBuilder Voir le message
Est-ce réellement intéressant de rajouter dans la jointure "id3 = 0 and id4 = 0" afin d'expliquer à Oracle qu'on cherche une unique ligne dans la jointure ?
Je dirais que oui, ça te permet de passer du RANGE SCAN à l'UNIQUE SCAN

Code :
1
2
3
4
5
6
7
8
9
10
11
SQL> SELECT * FROM t WHERE id1=1 AND id2=1
 
       ID1        ID2        ID3        ID4       VAL1       VAL2       VAL3
---------- ---------- ---------- ---------- ---------- ---------- ----------
         1          1          0          0          1          1          1
 
Execution Plan
----------------------------------------------------------
   0       SELECT STATEMENT Optimizer Mode=ALL_ROWS (Cost=4 Card=1 Bytes=21)
   1    0    TABLE ACCESS BY INDEX ROWID T (Cost=4 Card=1 Bytes=21)
   2    1      INDEX RANGE SCAN SYS_C0032014 (Cost=3 Card=1)
Code :
1
2
3
4
5
6
7
8
9
10
11
12
SQL> SELECT * FROM t WHERE id1=1 AND id2=1 AND id3=0 AND id4=0
 
       ID1        ID2        ID3        ID4       VAL1       VAL2       VAL3
---------- ---------- ---------- ---------- ---------- ---------- ----------
         1          1          0          0          1          1          1
1 row selected.
 
Execution Plan
----------------------------------------------------------
   0       SELECT STATEMENT Optimizer Mode=ALL_ROWS (Cost=3 Card=1 Bytes=21)
   1    0    TABLE ACCESS BY INDEX ROWID T (Cost=3 Card=1 Bytes=21)
   2    1      INDEX UNIQUE SCAN SYS_C0032014 (Cost=2 Card=1)
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/09/2011, 11h34   #5
Membre Expert
 
Homme Sylvain Devidal
Chef de projets Générix
Inscription : février 2010
Messages : 1 062
Détails du profil
Informations personnelles :
Nom : Homme Sylvain Devidal
Âge : 33
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Chef de projets Générix
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2010
Messages : 1 062
Points : 1 515
Points : 1 515
C'est effectivement ce que je me suis toujours dit (et ce que j'applique habituellement). Au détail près que niveau performances, je n'ai jamais vu de différence.

Ceci dit, comme je disais "au cas où" le paramétrage changerait, je pense qu'il est de toute façon plus prudent de remettre tous les champs de la clé, ça évitera d'avoir une démultiplicatin des lignes si un jour on se retrouve avec id3 ou id4 != 0...
StringBuilder est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/09/2011, 14h59   #6
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 311
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
Localisation : France, Marne (Champagne Ardenne)

Informations professionnelles :
Activité : Ingénieur développement logiciels
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : octobre 2007
Messages : 3 311
Points : 5 813
Points : 5 813
Citation:
Envoyé par StringBuilder Voir le message
C'est effectivement ce que je me suis toujours dit (et ce que j'applique habituellement). Au détail près que niveau performances, je n'ai jamais vu de différence.
...
Il est difficile de mettre en évidence l’effet ou il faut un test avec beaucoup des lectures. Dans le cas A) Oracle va lire le block racine de l’index va descendra ensuite jusqu’au block qui contient la clé (id1, id2, id3, id4) et ensuite va parcourir les ensembles des clés (id1, id2, X, Y). Mais comme id3 et id4 ont une seule et unique valeur 0 cela est assez proche du cas B) où Oracle descend l’index via la racine jusqu’au la clé unique cette fois (Id1, id2, id3, id4)
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 20h01.


 
 
 
 
Partenaires

Hébergement Web