cs_josserand
Messages postés14Date d'inscriptionvendredi 11 juin 2004StatutMembreDernière intervention18 octobre 2006
-
18 oct. 2006 à 14:34
mementosql
Messages postés4Date d'inscriptionsamedi 23 août 2008StatutMembreDernière intervention27 août 2008
-
23 août 2008 à 15:58
Bonjour,
J'ai besoin de créer des requêtes de mises à jour, appelant une sous-requête. Du genre :
<!-- BEGIN TEMPLATE: bbcode_code -->
Code :
UPDATE TABLE1 T1
SET T1.CHAMP1 =
(
SELECT T2.CHAMP1
FROM TABLE2 T2
WHERE T1.CHAMP2 = T2.CHAMP2
);
<!-- END TEMPLATE: bbcode_code -->
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 ?
cs_josserand
Messages postés14Date d'inscriptionvendredi 11 juin 2004StatutMembreDernière intervention18 octobre 2006 18 oct. 2006 à 15:48
Je n'ai aucune condition à mettre après le update, puisque je dois le faire sur toute la table.
Pour ta 2ème solution, ça pourrait m'offrir un début de solution... Mais je n'ai pour le moment pas réussi à trouver le moyen de créer des variables sous Oracle, différent de SQL Server, en effet.
Cette solution amène une autre question : @n peut-il être un tableau ? Puisque le SELECT va ramener autant de valeur qu'il y a d'enregistrements.
En attendant, je vais essayer d'approfondir cette solution, je te remercie.
cs_josserand
Messages postés14Date d'inscriptionvendredi 11 juin 2004StatutMembreDernière intervention18 octobre 2006 18 oct. 2006 à 17:59
Oui, dans le cas où j'effectue mon SELECT tout seul, plusieurs valeurs sont renvoyées. Par contre, quand ce même SELECT est dans un UPDATE (cf. ma requête du 1er message), une seule valeur est renvoyé, en jointure avec la table à mettre à jour... donc, pas d'erreur.
Pour me renvoyer une seule valeur, mon SELECT seul devrait ressembler à
SELECT T2.CHAMP1
FROM TABLE2 T2
WHERE T2.CHAMP2 = 'maValeur';
et non à
SELECT T2.CHAMP1
FROM TABLE2 T2, TABLE1 T1
WHERE T1.CHAMP2 = T2.CHAMP2;
En gros, pour que je puisse me servir de ça, il faudrait que j'arrive à stocker toutes les valeurs dans un tableau, pour ensuite faire mon UPDATE par rapport à chaque valeur de ce tableau (du style avec une boucle pour avoir Tab[i])...
Bref, ne nous fatiguons plus sur ce problème... si ce n'est pour notre culture du SQL, car j'ai trouvé la solution avec un logiciel de gestion de données : Sunopsis... Il me fait ça en quelques secondes !
Merci à toi, et si tu as compris mes contraintes et que tu connais la réponse, je reste à l'écoute
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_Malkuth
Messages postés268Date d'inscriptionsamedi 22 février 2003StatutMembreDernière intervention24 avril 20134 19 oct. 2006 à 13:52
Sous SQL Server tu peux faire :
UPDATE
TABLE1 T1
SET
CHAMP1 = T2.CHAMP1
FROM
TABLE1 T1
INNER JOIN
TABLE2 T2
ON T1.CHAMP2 = T2.CHAMP2;
En effet si une seule table peut être mise a jour,
on peut par contre utiliser les autres directement
Pour récupérer les valeurs, faire des jointure,
établir des conditions...
Je pense que le code est facilement transpossable à Oracle...
mementosql
Messages postés4Date d'inscriptionsamedi 23 août 2008StatutMembreDernière intervention27 août 20081 23 août 2008 à 15:58
Sous Oracle, l update via jointure peut tout a fait etre effectué comme énoncé iniatialement,
Le probleme, tu l as dis c'est le fait que ta sous requete mette 12s.
Essaies, si tu peux, de mettre un index sur t2.champs2, et ensuite, puisque que seul un enregistrement doit etre présent, ajoute and rownum = 1, ca peut aider.
Enfin, ne pense pas que la sous requete est exécutée autant de fois qu'il y a de mise à jour, oracle optimise ca en interne.
en gros essaie d optimiser ton select (ta jointure), la mise à jour suivra.