Bonjour bonjour
J'aurais besoin de votre avis sur une optimisation de procèdure stockée. Celle-ci est assez longue donc je n'ai pas pris le temps de l'anonymiser mais ma demande est plus sur le théorique :
Je dois récupérer une procédures qui fait plusieurs actions mais à chaque fois du même type :
- 4 Curseurs différents avec, à chaque fois, une requête sur au moins 3 tables. Des filtres utilisant les index.
- 4 Boucles (spoiler alert, une par curseur) parcourant le curseur, faisant au moins un IF sur une colonne du curseur pour y changer des données
Exemple :
- Dans chacun des curseurs, un update puis un delete.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 for ligne in curseur1 loop IF ligne.macolonne = 'FI' THEN ligne.registre = 0 END IF
L'update met à jour des tables produits, le delete supprime le produit mis à jour d'une table "d'attente de mise à jour".
Le souci c'est que le code est bof provoquant ainsi des millions de delete/update alors qu'il n'y a clairement pas autant de lignes.
Pour l'optimisation, et ca va être là où j'ai besoin d'un avis, j'imaginais 3 étapes :
1) Revoir les requêtes SELECT qui sont dans les curseurs
2) Virer les clauses IF pour les mettre dans des CASE directement dans les SELECT
3) Virer les curseurs et les loop pour passer à un update avec select et la petite option RETURNING comme sur l'exemple suivant :
Et me servir de la boucle pour la clause DELETE.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 DECLARE TYPE t_tab IS TABLE OF t1.id%TYPE; l_tab t_tab; BEGIN UPDATE t1 SET description = description RETURNING id BULK COLLECT INTO l_tab; FOR i IN l_tab.first .. l_tab.last LOOP DBMS_OUTPUT.put_line('UPDATE ID=' || l_tab(i)); END LOOP;
C'est sur le 3éme point que j'ai besoin de votre avis. Sur le papier, virer les curseurs pour passer par une requête directe me semble bien, surtout qu'en utilisant le RETURNING ensuite je peux enchainer le delete associé sans (normalement) de difficulté.
Est-ce une idée à la noix ?
Bisous bisous
Partager