[Oracle] Optimisation d'une requête de mise à jour

Optimisation d'une requête de mise à jour [Oracle] - SQL/NoSQL - Programmation

Marsh Posté le 18-10-2006 à 14:24:50    

Bonjour,
 
J'ai besoin de créer des requêtes de mises à jour, appelant une sous-requête. Du genre :
 

Code :
  1. UPDATE TABLE1 T1
  2. SET T1.CHAMP1 =
  3. (
  4. SELECT T2.CHAMP1
  5. FROM TABLE2 T2
  6. WHERE T1.CHAMP2 = T2.CHAMP2
  7. );


 
 
Seulement, cette requête met 4H pour mettre à jour 300 000 lignes. Normal, puisque pour chaque ligne, elle effectue une requête qui, elle seule, met 12 secondes.
 
Connaitriez-vous un moyen d'éviter d'exécuter la sous-requête pour chaque ligne à mettre à jour, ou, plus généralement, un moyen d'optimiser cette requête ?
 
Merci pour votre éventuelle aide  :)

Reply

Marsh Posté le 18-10-2006 à 14:24:50   

Reply

Marsh Posté le 18-10-2006 à 15:36:24    

Tu as un index sur T2.CHAMP2 ?

Reply

Marsh Posté le 18-10-2006 à 15:41:38    

je te rassure, il ne fait pas le select pour chaque ligne. du moins, pas si ta requête est effectivement aussi simple que ce que tu as écrit. l'optimiseur se rend immédiatement compte qu'en fait tu fais une simple jointure.
 
à ma connaissance, oralce ne supporte pas d'autre syntaxe pour faire ce genre de requêtes, contrairement à SQL Server par exemple, qui supporte des jointures explicites dans les requêtes de mise à jour.

Reply

Marsh Posté le 18-10-2006 à 15:53:05    

beegee, au risque de passer pour un nul (mais je ne suis pour autant un pro du SQL), à quoi sert un index en général ?
 
MagicBuzz, pourtant, lorsque je fais un update simple, sans sous-requête, ça ne prend que quelques secondes (au lieu de 4H), genre :
 

Code :
  1. UPDATE TABLE1 T1
  2. SET T1.CHAMP1 = NULL;

Reply

Marsh Posté le 18-10-2006 à 15:58:29    

Un index sur les colonnes A1 ... An d'une table, permet d'accéder rapidement aux données de la table lorsqu'on l' "attaque" avec ces colonnes (ou au moins avec la première partie de ces colonnes, A1 ... Am avec m < n).
 
Dans ton cas, si tu as un index sur T2.CHAMP2 (ou sur T2.CHAMP2 et d'autres champs, mais avec T2.CHAMP2 en tête de l'index), alors le sous-select accèdera rapidement aux données de la table T2.
Ton temps mesuré de 12s me fait penser au fait que cet index n'existe pas.

Reply

Marsh Posté le 18-10-2006 à 16:17:24    

josserand_ joss >
 
select t1.champ1, t2.champ1
from t1, t2
where t1.champ2 = t2.champ2
 
=> ça met combien de temps ? 12 secondes ?


Message édité par MagicBuzz le 18-10-2006 à 16:18:03
Reply

Marsh Posté le 18-10-2006 à 16:18:44    

je mettrais un where exists sur le update avec la même requete que pour setter la value.

Reply

Marsh Posté le 18-10-2006 à 18:13:50    

beegee >
 
Ok, je note pour l'index... Dis-moi si je me trompe dans ce que j'ai compris :
sans index, la requête va parcourir les enregistrements pour trouver la bonne ligne, alors qu'avec un index, il va directement aller au bon enregistrement... J'ai bon ?
 
 
MagicBuzz >
 
Oui, ça met bien 12 secondes.
 
 
anapajari >
 
Je n'ai pas bien compris ce à quoi tu penses.
 
 
tous >
 
En parallèle, j'ai utilisé un logiciel de gestion de données (Sunopsis) qui m'a permis d'effectuer mon traitement en quelques secondes (au lieu de 4H)... donc, ça résouds mon problème. Cela dit, j'aimerais quand même bien connaître la solution avec une requête à la main... Peut-être les index pourraient m'aider.
 
Merci bien  :)

Reply

Marsh Posté le 18-10-2006 à 18:36:46    

En effet, si tu crées un index sur T2.CHAMP2, au lieu de parcourir toute la table pour trouver les enregistrements correspondant au filtre de recherche, tu vas directement dessus ...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed