Update Oracle 10g massif optimisé / Merge

Oracle 10g apportait dans son lot de nouveautés l’instruction MERGE qui correspond à un INSERT or UPDATE, mode d’alimentation bien connu de nos chers ETL.
Les ETL gérant ce mode très bien, j’avoue n’en avoir jamais vu l’utilité, à part la simplification d’écriture dans un script SQL quand on n’a pas d’ETL sous la main.
Jusqu’à ce que je tombe sur un Update somme toute assez classique mais qui durait des plombes.

On a une table « echeancier » avec un identifiant, une date et un montant.
L’update fait la somme des montants à venir :

UPDATE avenir
SET montant=(SELECT sum(montant) FROM echeancier
WHERE echeancier.id=avenir.id
AND echeancier.datecheance > :dateparametre
AND ( autres filtres ) ;

Oracle utilise bien les index, mais comme la volumétrie est importante, la mise à jour est très longue ( 1h15 ).

La solution classique est de passer par une table temporaire, puis de faire l’update. Mais il faut pouvoir créer une table, voire gérer les droits … Bref, pas très pratique.

Le Merge permet de faire un update massif, sans passer par une table intermédiaire.

Le sql transformé donne :

MERGE INTO avenir  
USING  
( SELECT id, sum(montant) montant
FROM echeancier
WHERE echeancier.datecheance > :dateparametre
AND ( autres filtres )   ) x
ON ( avenir.id = x.id )
WHEN MATCHED THEN UPDATE SET montant=x.montant;

Oracle n’utilise plus les index, mais on passe de 1h 15 à 2′ 20.
( 2’40 en passant par une table temporaire )

Que du bonheur

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>