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 16/01/2008, 01h25   #1
Membre régulier
 
Avatar de jacquesh
 
Développeur informatique
Inscription : février 2005
Messages : 269
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2005
Messages : 269
Points : 82
Points : 82
Par défaut [XMLTYPE] - Index - TABLE ACCESS FULL

bonjour,

voila plus jour que je galère sur l'impossibilité de me débarrasserd'un "TABLE ACCESS FULL" !!

J'ai une table comme suit les documents XML font ~30ko.
Code :
1
2
3
4
5
CREATE TABLE XYZREGISTRE of XMLType
    XMLTYPE store AS OBJECT RELATIONAL
    XMLSCHEMA "http://X.Y.Z/projet/ABC/schema/xyzmessage.xsd"
	ELEMENT "xyzmessage"
/
Plein d'index de ce genre.
Code :
1
2
CREATE INDEX idx_xyzreg_1 ON XYZREGISTRE
	(extractvalue(object_value,'/xyzmessage/META_DATA/md_hopcreator')) TABLESPACE INDX;
si je fait un requete que ne recupère que 1 champs (indexé) par de pb.

par contre comment peut on optimiser cette requete :
Code :
SELECT extract(object_value,'/xyzmessage').getClobVal() FROM XYZREGISTRE WHERE existsNode(object_value,'/xyzmessage[NOID="x007tzg4263') = 1;
Code :
1
2
3
4
5
6
7
8
9
10
11
 
-----------------------------------------------------------------------------------------------------------------
| Id  | Operation            | Name        | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |             |     1 |  2548 |     2   (0)| 00:00:01 |        |      |            |
|   1 |  PX COORDINATOR      |             |       |       |            |          |        |      |            |
|   2 |   PX SEND QC (RANDOM)| :TQ10000    |     1 |  2548 |     2   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   3 |    PX BLOCK ITERATOR |             |     1 |  2548 |     2   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|*  4 |     TABLE ACCESS FULL| XYZREGISTRE |     1 |  2548 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
 
 4 - filter("XYZREGISTRE"."SYS_NC00017$"='x007tzg4263')

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
Statistiques
----------------------------------------------------------
         37  recursive calls
          3  db block gets
       5206  consistent gets
          0  physical reads
        628  redo size
       1065  bytes sent via SQL*Net TO client
        674  bytes received via SQL*Net FROM client
          5  SQL*Net roundtrips TO/FROM client
          1  sorts (memory)
          0  sorts (disk)
          1  rows processed
pour eviter un access full.
note :: le .getClobVal() est OBLIGATOIRE.

merci de votre aide !!
__________________
Citation:
En essayant continuellement on finit par réussir. Donc : plus ça rate, plus on a de chance que ça marche.
jacquesh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 09h10   #2
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 319
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 319
Points : 5 837
Points : 5 837
Et pour quoi veut tu te débarrasser du FULL ? Les résultats n’ont pas l’air d’indiquer un souci de performance ?
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 09h29   #3
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
j'y connais pas grand chose (en fait rien ) mais d'après l'exemple de la doc j'ai pas l'impression que l'index porte sur la même chose que la requête.

Je me serais attendu à un WHERE du genre :
Code :
object_value,'/xyzmessage[META_DATA="x007tzg4263'
ou trouver NOID dans l'index

Sinon, sache qu'il n'est pas forcément intéressant de passer par un index, si Oracle ramène beaucoup de ligne (par rapport au nombre de référence dans l'index) un FTS est plus intéressant
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 09h31   #4
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
cet exemple à l'air intéressant aussi : http://download.oracle.com/docs/cd/B...tm#sthref10107

tu peux essayer un index comme ça ?
Code :
CREATE INDEX idx_xyzreg_1 ON XYZREGISTRE (XMLDATA."NOID")
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 16h10   #5
Membre régulier
 
Avatar de jacquesh
 
Développeur informatique
Inscription : février 2005
Messages : 269
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2005
Messages : 269
Points : 82
Points : 82
en fait j'ai tourné le problème un peu dans tous les sens.

en effet il n'y a pas problème de perf - pour le moment - c'est une base de dev.
J'ai fait des test d'accès à 100, 1000, 10000 lignes ça fonctionne avec des temps d'accès <3sec... mais pour plus tard...

Les temps données par explain plan sont un peu faussé lorsque la requête a déjà été exécuté...

en ce qui concerne le fait d'utiliser "WHERE extractValu"e au lieu de "/xpath[param=value] "; j'ai remarqué que c'était moins couteux en E/S pour oracle - Maintenant savoir pourquoi ?-

la ou cela me pose problème. c'est que Oracle n'utilise pas les index que j'ai mis en place.

Autre exemple :

quand je fait un
Code :
1
2
SELECT * FROM TOTO WHERE ROWID=(
SELECT ROWID FROM TOTO WHERE A=1) ;
exemple avec XMLTYPE
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
SELECT extract(object_value,'/abcmessage').getClobVal() FROM XYZREGISTRE WHERE rowid=(
SELECT rowid FROM XYZREGISTRE WHERE existsNode(object_value,'/abcmessage[NODC="fj65743Hde"]') = 1);
-----------------------------------------------------------------------------------------------------------------------
| Id  | Operation                  | Name        | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |             |     1 |  2548 |     3   (0)| 00:00:01 |        |      |            |
|*  1 |  FILTER                    |             |       |       |            |          |        |      |            |
|   2 |   FAST DUAL                |             |     1 |       |     2   (0)| 00:00:01 |        |      |            |
|   3 |  TABLE ACCESS BY USER ROWID| XYZREGISTRE |     1 |  2548 |     1   (0)| 00:00:01 |        |      |            |
|   4 |   PX COORDINATOR           |             |       |       |            |          |        |      |            |
|   5 |    PX SEND QC (RANDOM)     | :TQ10000    |     1 |  2548 |     2   (0)| 00:00:01 |  Q1,00 | P->S | QC (RAND)  |
|   6 |     PX BLOCK ITERATOR      |             |     1 |  2548 |     2   (0)| 00:00:01 |  Q1,00 | PCWC |            |
|*  7 |      TABLE ACCESS FULL     | XYZREGISTRE |     1 |  2548 |     2   (0)| 00:00:01 |  Q1,00 | PCWP |            |
-----------------------------------------------------------------------------------------------------------------------
L'index est bien utilisé pour le rowID, par contre le fait de mettre * ou une liste de champs que je souhaite récupérer l'explain fini par un ACCESS FULL !!

De plus je n'arrive pas a forcer l'usage des index même avec /*index()*/ dans la requete !!

une idée...
__________________
Citation:
En essayant continuellement on finit par réussir. Donc : plus ça rate, plus on a de chance que ça marche.
jacquesh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 16h34   #6
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 319
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 319
Points : 5 837
Points : 5 837
Si t’a pas un problème de perf ne t’invente pas un problème d’optimisation !
Si tu penses que les gros volumes vont poser des problèmes fais un benchmark et vérifiez.
Si tu veut obtenir les informations concernant les choix de l’optimiseur fait une trace de l’événement 10053, mais comprendre et interpréter les résultats n’est pas simple. Il y a « N » raisons pour expliquer pourquoi Oracle n’utilise un index.
Citation:
Les temps données par explain plan sont un peu faussé lorsque la requête a déjà été exécuté...
C'est pas vrai. Mais tu peut faire un
Code :
1
2
 
ALTER system FLUSH shared_pool
si tu pense que ça aide.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 17h52   #7
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
si je vois bien tu utilises le parallélisme ce qui peut expliquer l'usage des FTS
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 18h05   #8
Membre éprouvé
 
Inscription : décembre 2007
Messages : 354
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 354
Points : 408
Points : 408
Citation:
SELECT * FROM TOTO WHERE ROWID=(
SELECT ROWID FROM TOTO WHERE A=1) ;
C'est très curieux comme approche!
Pourquoi ne pas faire
Code :
SELECT * FROM TOTO WHERE A=1
__________________
Consultant et formateur Oracle
Michel SALAIS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 20h52   #9
Membre régulier
 
Avatar de jacquesh
 
Développeur informatique
Inscription : février 2005
Messages : 269
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2005
Messages : 269
Points : 82
Points : 82
Citation:
Envoyé par Michel SALAIS Voir le message
C'est très curieux comme approche!
Pourquoi ne pas faire
Code :
SELECT * FROM TOTO WHERE A=1
parce que suivant la configuration de l'XML TABLE même avec un index j'ai
Code :
1
2
 
SELECT F1 FROM toto WHERE A=1
la tout va bien

par contre
Code :
SELECT * FROM  toto WHERE A=1
TABLE ACCESS FULL !!

je me suis dit que si je trouve rapidement le rowid, ramener toutes les informations de ce rowid serai une facon d'aider oracle à trouver l'information sans tout scanner....
mais malheureusement TABLE ACCESS FULL !! too.

bizard... vous avez dis bizard

pour répondre à "orafrance" : j'ignorai que le parallélisme imposait le FTS... je vais fouiller dans cette direction.

merci pour l'info
__________________
Citation:
En essayant continuellement on finit par réussir. Donc : plus ça rate, plus on a de chance que ça marche.
jacquesh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 21h06   #10
Membre régulier
 
Avatar de jacquesh
 
Développeur informatique
Inscription : février 2005
Messages : 269
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : février 2005
Messages : 269
Points : 82
Points : 82
Bingo !!

c'était bien le parallélisme qui provoquai le non-usage des index !!
si quelqu'un a de ma littérature sur le sujet;je suis preneur.

Merci encore.

SOLVED
__________________
Citation:
En essayant continuellement on finit par réussir. Donc : plus ça rate, plus on a de chance que ça marche.
jacquesh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 22h51   #11
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
qui dit parallélisme dit FTS moins couteux pour l'optimiseur donc le CBO rechigne moins à y recourir

c'est pas automatique mais ça risque d'arriver plus souvent... encore une démonstration que le parallélisme est loin d'être toujours miraculeux
orafrance 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 08h08.


 
 
 
 
Partenaires

Hébergement Web