par , 17/03/2016 à 18h34 (2782 Affichages)
Bonjour,
Préambule : n'étant pas un administrateur de base de données et n'ayant pas l'ensemble des compétences correspondantes, je ne vais pas faire un billet "Voilà comment en fait", mais plutôt "Voilà ce que j'ai utilisé et qui fonctionne dans mon cas".
Ce mois ci, il m'a été demander de faire un script SQL "Optimisé" pour un traitement concernant plusieurs table ayant d’énorme volume de données. L'ordre de grandeur étant le milliard...
Dans ce cadre, les requêtes les plus simple peuvent prendre un temps fou :
Par exemple :
select count(*) from ma_table;
Prendre environ 40 minutes.
Dans ce contextes les adminstrateur de base de données avec qui je travail m'ont vite indiqué qu'il était préférable d'utiliser une HINT, afin de demander à la base de donnée de faire la requête sur plusieurs thread :
select /*+ PARALLEL( ma_table,6) */ count(*) from ma_table;
Cette version prendre entre 2 et 4 minutes.
Note : Pour ma part, Oracle doit faire une gestion plus intelligente dans ce cas, car même en multipliant par le nombre de thread utilisées le temps parallélisé, on est toujours inférieur au temps de départ.
Il y a d'ailleurs un sujet sur le forum ayant ce même constat : [11gR2] Tablespace index full : problème pour faire une requête?
Le même HINT fonctionne pour les insertions (dans une moindre mesure). Je n'ai pas eu à le tester dans le cas du delete, mais la documentation oracle indique que cela est aussi possible.
L'optimisation de l'insertion :
insert /*+ APPEND */ into /*+ PARALLEL(ma_nouvelle_table,6) */ ma_nouvelle_table select * from mon_ancienne_table;
Ici, il y a plusieurs chose à savoir :
- L'appends indique à Oracle ne cherche pas à voir si tu peux réutiliser un trou, ajout à la fin.
- Le HINT pour avoir un parallélisme de 6.
- Il est nécessaire de faire un commit après la requête d'insertion, avant toute nouvelle requête sur la table.
Update a la même problématique que l'insert.
Pour le create table et le create index, ce n'est pas la même syntaxe, mais c'est la même logique :
create table ma_nouvelle_table parallel (degree 6) nologging as select * from mon_ancienne_table;
Note : nologging pour indiquer à oracle "Pas besoin de log sur l'opération".
1 2 3 4 5
| CREATE INDEX INDEX_MA_TABLE on MA_TABLE (MA_COLONNE)
NOLOGGING
PARALLEL 6;
-- On repasse en non parallel après sa création pour une utilisation normal !
ALTER INDEX INDEX_MA_TABLE NOPARALLEL; |
Pour la fin, il y a les commandes pratique pour l'analyse :
1 2 3 4 5 6
| --Affiche la durée de la requête après le résultat.
SET TIMING ON;
-- Explain plan d'oracle en ligne de commande SQL, si l'environnement ne fournit pas mieux :
explain plan for **Ma requête**;
-- Affichage du plan d'exécution :
select * from table(dbms_xplan.display); |
Note : Il est possible qu'il soit nécessaire d'activé la parallélisation DML pour la session pour que la parallélisation soit pris en compte :
ALTER SESSION ENABLE PARALLEL DML;
Enfin, tout cela pour dire que j'ai vue plein de chose lié à Oracle que je n'avais jamais eu besoin d'utiliser.Et je pense que ces informations peuvent resservir. (au moins pour moi ) N’hésitez pas à me reprendre si j'ai dit une ânerie !
Cordialement,
Patrick Kolodziejczyk.
Source :
Using Parallel Execution
APPEND