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 29/04/2008, 17h31   #1
Membre Expert
 
Homme sébastien
Développeur informatique
Inscription : octobre 2006
Messages : 1 173
Détails du profil
Informations personnelles :
Nom : Homme sébastien
Âge : 29
Localisation : Argentine

Informations professionnelles :
Activité : Développeur informatique
Secteur : Finance

Informations forums :
Inscription : octobre 2006
Messages : 1 173
Points : 1 372
Points : 1 372
Envoyer un message via Skype™ à Vld44
Par défaut [9i] FULL TABLE SCAN sur colonne entrant dans la PK

Salut,

Soit la table suivante :

Code :
1
2
CREATE TABLE ARF_TEMP_myIds(INSTANCEID VARCHAR2(44));
ALTER TABLE ARF_TEMP_myIds ADD CONSTRAINT PK_MYIDS PRIMARY KEY (INSTANCEID);
mes jointures avec cette table me font systématiquement un full scan et je ne comprends pas pourquoi. Est-ce que cela veut aussi dire que l'index ne sert à rien ?

Merci

edit : je précise qu'elles sont "conventionnelles" c'est à dire de type where A = B
Vld44 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 17h39   #2
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
Non, ça veut dire qu'Oracle a décidé de ne pas aller lire l'index suivant les paramètres de l'optimiseur.

1/ Les stats sont elles à jour ?
2/ La table est elle grosse (parce que sinon c'est plus simple de monter toute la table en mémoire)
3...
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 17h41   #3
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 320
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 320
Points : 5 839
Points : 5 839
Il faut ajouter quelques détails.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
EXPLAIN plan FOR 
SELECT * 
FROM ARF_TEMP_myIds a JOIN ARF_TEMP_myIds b USING (INSTANCEID)
/
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
 
-------------------------------------------------------------------------
| Id  | Operation            |  Name       | Rows  | Bytes | Cost (%CPU)|
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |    82 |  3936 |     4   (0)|
|   1 |  NESTED LOOPS        |             |    82 |  3936 |     4   (0)|
|   2 |   INDEX FULL SCAN    | PK_MYIDS    |    82 |  1968 |    26   (0)|
|*  3 |   INDEX UNIQUE SCAN  | PK_MYIDS    |     1 |    24 |            |
-------------------------------------------------------------------------
 
Predicate Information (IDENTIFIED BY operation id):
 
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
---------------------------------------------------
 
   3 - access("A"."INSTANCEID"="B"."INSTANCEID")
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 17h41   #4
Membre Expert
 
Homme sébastien
Développeur informatique
Inscription : octobre 2006
Messages : 1 173
Détails du profil
Informations personnelles :
Nom : Homme sébastien
Âge : 29
Localisation : Argentine

Informations professionnelles :
Activité : Développeur informatique
Secteur : Finance

Informations forums :
Inscription : octobre 2006
Messages : 1 173
Points : 1 372
Points : 1 372
Envoyer un message via Skype™ à Vld44
ah bien vu, je créé à la volée la table et l'index donc aucune stat n'est à jour.

Cependant je sais à tout moment le compte de la table, puis-je forcer le compilateur à une cardinalité donnée ? il me semble avoir vu passer une syntaxe avec "(cardinalité)" ...
Vld44 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 17h44   #5
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
Je n'ai pas compris ta notion de cardinalité.
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 17h47   #6
Membre Expert
 
Homme sébastien
Développeur informatique
Inscription : octobre 2006
Messages : 1 173
Détails du profil
Informations personnelles :
Nom : Homme sébastien
Âge : 29
Localisation : Argentine

Informations professionnelles :
Activité : Développeur informatique
Secteur : Finance

Informations forums :
Inscription : octobre 2006
Messages : 1 173
Points : 1 372
Points : 1 372
Envoyer un message via Skype™ à Vld44
et bien puisque l'optimiseur n'a pas de statistiques au moment des requêtes, ne pourrais-je pas les lui spécifier ? (contenu de la table à l'instant t)

/*+ CARDINALITY (100) */

par exemple ... Il faut que je bosse mon pl/sql ><


edit : je suis sous 9i !!!
Vld44 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 21h39   #7
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 320
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 320
Points : 5 839
Points : 5 839
Je n'ai pas calculé les statistique dans mon exemple et l'index est utilisé (la tables est vide).
Peut tu mieux expliquer quel est ton problème ?
Sinon il y a un hint SQL concernant la cardinalité mais est-ce que t'a vraiment besoin ?
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 10h38   #8
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
un exemple de requête ça pourrait être pas mal déjà... est-ce qu'il y une clause WHERE sur la colonne de la PK au moins ?
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 12h54   #9
Membre Expert
 
Homme sébastien
Développeur informatique
Inscription : octobre 2006
Messages : 1 173
Détails du profil
Informations personnelles :
Nom : Homme sébastien
Âge : 29
Localisation : Argentine

Informations professionnelles :
Activité : Développeur informatique
Secteur : Finance

Informations forums :
Inscription : octobre 2006
Messages : 1 173
Points : 1 372
Points : 1 372
Envoyer un message via Skype™ à Vld44
ce qu'il y a c'est que j'aurais bien une requête complète à vous fournir mais elle est un peu nébuleuse sortie de son contexte quoi ...

La voilà, avec la jointure en gras :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
MERGE INTO TABLE0 op
USING
    (
     SELECT ids.instanceid, rv.id
     FROM ARF_TEMP_myIds ids, TABLE1 oi, TABLE2 rv
     WHERE ids.instanceid = oi.id
     AND   rv.name = (oi.name || '-' || '1278')
     AND   oi.conceptid = 'CODMETHODBIN'
    ) raws
ON (op.instanceid = raws.instanceid AND op.propertyid = '1278')
WHEN MATCHED THEN
    UPDATE SET op.rawvalue = raws.id
WHEN NOT MATCHED THEN
    INSERT (op.instanceid, op.propertyid,op.propvalue,op.rawvalue)
    VALUES (raws.instanceid,'1278',NULL,raws.id)
Voici l'explain plan associé avec en gras la ligne qui parle du full scan :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
MERGE STATEMENT, GOAL = CHOOSE   Cost=9    Cardinality=1    Bytes=121
 MERGE    Object name=TABLE0 
  VIEW                    
   NESTED LOOPS OUTER  Cost=9    Cardinality=1    Bytes=306
    NESTED LOOPS            Cost=6    Cardinality=1    Bytes=257
     MERGE JOIN CARTESIAN   Cost=4    Cardinality=1    Bytes=177
 TABLE ACCESS FULL Object name=TABLE2 Cost=2 Cardinality=1 Bytes=153
      BUFFER SORT            Cost=2    Cardinality=82    Bytes=1968
       TABLE ACCESS FULL    Object name=ARF_TEMP_MYIDS    Cost=2    Cardinality=82    Bytes=1968
     TABLE ACCESS BY INDEX ROWID  Object name=TABLE1 Cost=2    Cardinality=1    Bytes=80
      INDEX UNIQUE SCAN  Object name=PK_TABLE1 Cost=1 Cardinality=1    
    TABLE ACCESS BY INDEX ROWID  Object name=TABLE0 Cost=3    Cardinality=1    Bytes=49
     INDEX UNIQUE SCAN  Object name=PK_TABLE0 Cost=2 Cardinality=1
Voilà ...
Vld44 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 13h45   #10
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
bah voila, il y a tellement peut de ligne que ça sert à rien de faire un accès par l'index.

Faut pas croire que FTS = perf catastrophique, c'est un peu plus fin que ça En effet, dans le cas présent Oracle ne lit que le fichier de données au lieu de lire index + données ce qui est trop couteux quand la table est petite
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 14h11   #11
Membre Expert
 
Homme sébastien
Développeur informatique
Inscription : octobre 2006
Messages : 1 173
Détails du profil
Informations personnelles :
Nom : Homme sébastien
Âge : 29
Localisation : Argentine

Informations professionnelles :
Activité : Développeur informatique
Secteur : Finance

Informations forums :
Inscription : octobre 2006
Messages : 1 173
Points : 1 372
Points : 1 372
Envoyer un message via Skype™ à Vld44
la table est remplie dans une transaction et peut contenir plusieurs millions d'enregistrements.

tu veux dire que dans ce dernier cas, l'index serait utilisé ?
Vld44 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 14h27   #12
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 320
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 320
Points : 5 839
Points : 5 839
J'aimerai bien avoir un desc de la table Table1 pour analyser le type de données de la colonne id.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 14h34   #13
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
Citation:
Envoyé par Vld44 Voir le message
tu veux dire que dans ce dernier cas, l'index serait utilisé ?
si la requête ne ramène pas un trop gros échantillon et que les stats sont à jour, oui
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 14h54   #14
Membre Expert
 
Homme sébastien
Développeur informatique
Inscription : octobre 2006
Messages : 1 173
Détails du profil
Informations personnelles :
Nom : Homme sébastien
Âge : 29
Localisation : Argentine

Informations professionnelles :
Activité : Développeur informatique
Secteur : Finance

Informations forums :
Inscription : octobre 2006
Messages : 1 173
Points : 1 372
Points : 1 372
Envoyer un message via Skype™ à Vld44
Citation:
Envoyé par mnitu Voir le message
J'aimerai bien avoir un desc de la table Table1 pour analyser le type de données de la colonne id.
Code :
WHERE ids.instanceid = oi.id
oi.id : VARCHAR2(44)
ids.instanceid : VARCHAR2(44)

est-ce que au passage vous voyez des abérations dans mon code ?
Je suis pas hyper doué en pl/sql et ça m'étonnerait pas que j'ai fait une énormité
Vld44 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 15h34   #15
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 320
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 320
Points : 5 839
Points : 5 839
Citation:
Envoyé par Vld44 Voir le message
[code]...
est-ce que au passage vous voyez des abérations dans mon code ?
Je suis pas hyper doué en pl/sql et ça m'étonnerait pas que j'ai fait une énormité
J’avais pensé que si les colonnes n’ont pas le même type ça pouvait expliquer le full table scan par la conversion implicite fait dans ce cas par Oracle mais ce n’est pas le cas.
Sinon calcule les statistiques, examine le plan, charge les tables avec un test réel, recalcule les statistiques et examine le plan. Pour l’instant ce qui se passe est normal.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h49.


 
 
 
 
Partenaires

Hébergement Web