29 octobre 2008
3
29
/10
/octobre
/2008
21:09
Bonsoir,
L'autre soir, lorsque j'ai crée ma "big table" de 125 millions de lignes, j'ai eu quelques soucis.
http://www.lao-dba.com/article-24006948.html
declare
type t_reponse IS TABLE of Reponse_3%ROWTYPE;
l_reponse t_reponse := t_reponse();
BEGIN
FOR z IN 1..625 LOOP
FOR i IN 1..200000 LOOP
l_reponse.extend; /* On étend la taille du tableau */
/* Remplissage du table */
l_reponse(l_reponse.last).Q1 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q2 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q2 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q4 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q5 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q6 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q7 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q8 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q9 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q10 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).ID_PAYS :=Round(DBMS_RANDOM.VALUE(1,25));
l_reponse(l_reponse.last).ID_FORMULAIRE :=Round(DBMS_RANDOM.VALUE(1,100)); l_reponse(l_reponse.last).DATE_QUESTIONNAIRE :=Round(DBMS_RANDOM.VALUE(20071201,20071231));
END LOOP;
/* Insertion en masse */
FORALL i IN l_reponse.first..l_reponse.last
INSERT INTO Reponse_3 VALUES l_reponse(i);
COMMIT;
l_reponse.TRIM(200000); /*On vide le tableau,... sinon risque de problème de mémoire */
END LOOP;
END;
Tout d'abord, j'ai commencé par créer une structure identique à ma table Reponse_1. Pas très compliqué.
CREATE TABLE Reponse_3 AS SELECT * FROM Reponse_1 WHERE 1=0;
Ensuite, on déclare un Type qui correspond à un tableau de ligne de la table Reponse_3
Enfin on boucle pour alimenter notre tableau par paquet de 200000, et on appelle la commande FORALL, qui execute une insertion de masse qui sera beaucoup plus efficace qu'une insertion ligne à ligne.
Moralité de l'histoire, avant de foncer et de pondre du code, il peut être utile de se poser et de réfléchir aux différentes solutions possibles.
LAO.
L'autre soir, lorsque j'ai crée ma "big table" de 125 millions de lignes, j'ai eu quelques soucis.
http://www.lao-dba.com/article-24006948.html
- Au final, le serveur est parti en vrille, et je n'ai inséré que 115 millions de lignes.
- Cela a pris plusieurs heures (au moins 4 je crois me souvenir).
Finalement, cette durée était prévisible. Et pourtant le oracle par l'intermédiare du PL-SQL permet des choses impressionnantes.
J'ai donc décidé ce soir revisiter mon code d'insertion afin que cela ne prenne plus qu'une heure, et qu'il aille jusqu'au bout => 125 millions de lignes.
declare
type t_reponse IS TABLE of Reponse_3%ROWTYPE;
l_reponse t_reponse := t_reponse();
BEGIN
FOR z IN 1..625 LOOP
FOR i IN 1..200000 LOOP
l_reponse.extend; /* On étend la taille du tableau */
/* Remplissage du table */
l_reponse(l_reponse.last).Q1 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q2 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q2 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q4 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q5 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q6 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q7 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q8 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q9 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).Q10 :=Round(DBMS_RANDOM.VALUE(0,10));
l_reponse(l_reponse.last).ID_PAYS :=Round(DBMS_RANDOM.VALUE(1,25));
l_reponse(l_reponse.last).ID_FORMULAIRE :=Round(DBMS_RANDOM.VALUE(1,100)); l_reponse(l_reponse.last).DATE_QUESTIONNAIRE :=Round(DBMS_RANDOM.VALUE(20071201,20071231));
END LOOP;
/* Insertion en masse */
FORALL i IN l_reponse.first..l_reponse.last
INSERT INTO Reponse_3 VALUES l_reponse(i);
COMMIT;
l_reponse.TRIM(200000); /*On vide le tableau,... sinon risque de problème de mémoire */
END LOOP;
END;
Tout d'abord, j'ai commencé par créer une structure identique à ma table Reponse_1. Pas très compliqué.
CREATE TABLE Reponse_3 AS SELECT * FROM Reponse_1 WHERE 1=0;
Ensuite, on déclare un Type qui correspond à un tableau de ligne de la table Reponse_3
Enfin on boucle pour alimenter notre tableau par paquet de 200000, et on appelle la commande FORALL, qui execute une insertion de masse qui sera beaucoup plus efficace qu'une insertion ligne à ligne.
Moralité de l'histoire, avant de foncer et de pondre du code, il peut être utile de se poser et de réfléchir aux différentes solutions possibles.
LAO.