EDIT : message réintroduit suite à la panne de serveur
Bonjour,
J'ai une table contenant une colonne BFILE pointant vers des documents Word, Excel, PDF, etc sur un système de fichier. et je converti cette colonne en un contenu HTML pour une indexation future avec Oracle Text.
Ce que j'ai, une table contenant 3 millions d'enregistrements, le script de création volontairement réduit aux colonnes utiles pour cette discussion :
Une procédure qui boucle sur une plage de données de la table, convertissant pour chaque ligne la colonne DOC_BFILE en HTML dans la colonne DOC_CLOB via un convertisseur fourni par Oracle Text :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part CREATE TABLE DGTVISTA.VIS_DOCUMENTS_T ( DOC_ID NUMBER(10) NOT NULL, DOC_CLOB CLOB, DOC_BFILE BFILE )
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88 CREATE OR REPLACE PROCEDURE DGTVISTA.fast_way_byrange_OLD ( beginrownum NUMBER, endrownum NUMBER ) IS ltimestamp_start TIMESTAMP; ltimestamp_stop TIMESTAMP; linterval_diff INTERVAL DAY TO SECOND; n NUMBER := 0; c CLOB; TYPE ARRAY IS TABLE OF vis_documents_t%ROWTYPE; l_data ARRAY; TYPE parent_rec IS RECORD ( part_num DBMS_SQL.number_table, part_name DBMS_SQL.bfile_table ); p_rec parent_rec; CURSOR cur IS SELECT * FROM vis_documents_t WHERE doc_id IN (SELECT doc_id FROM (SELECT a.*, ROWNUM rnum FROM (SELECT doc_id FROM vis_documents_t) a WHERE ROWNUM <= endrownum) WHERE rnum >= beginrownum); BEGIN ltimestamp_start := SYSTIMESTAMP; DBMS_OUTPUT.put_line (ltimestamp_start); OPEN cur; LOOP FETCH cur BULK COLLECT INTO l_data LIMIT 2000; FOR i IN 1 .. l_data.COUNT LOOP BEGIN ctx_doc.policy_filter ('dgt_policy', l_data (i).doc_bfile, c); UPDATE vis_documents_t SET doc_clob = c WHERE doc_id = l_data (i).doc_id; EXCEPTION WHEN OTHERS THEN NULL; END; END LOOP; EXIT WHEN cur%NOTFOUND; END LOOP; CLOSE cur; COMMIT; ltimestamp_stop := SYSTIMESTAMP; DBMS_OUTPUT.put_line (ltimestamp_stop); linterval_diff := ltimestamp_stop - ltimestamp_start; DBMS_OUTPUT.put_line ( CHR (10) || LPAD ('=', 22, '=') || CHR (10) || ' Runtime Difference' || CHR (10) || LPAD ('=', 22, '=') ); DBMS_OUTPUT.put_line ( ' Days : ' || EXTRACT (DAY FROM linterval_diff) || CHR (10) || ' Hours : ' || EXTRACT (HOUR FROM linterval_diff) || CHR (10) || ' Minutes : ' || EXTRACT (MINUTE FROM linterval_diff) || CHR (10) || ' Seconds : ' || EXTRACT (SECOND FROM linterval_diff) ); END fast_way_byrange_OLD; /
Pour exécuter cette procédure, j'ai un script sous Unix qui lance en tâche de fond 5 fois un autre script (voir script suivant) responsable d'exécuter la procédure vue précédemment :
( NB : $DU $DP $DD sont les identifiants de connexions à la base de données Oracle, et les 2 derniers paramètres les bornes pour la procédure stockée vue précédemment )
Le script single_part_tab.sh responsable d'appeler la procédure stockée vue au dessus :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 ( ./single_part_tab.sh $DU $DP $DD 0 50000 ) & ( ./single_part_tab.sh $DU $DP $DD 50001 100000 ) & ( ./single_part_tab.sh $DU $DP $DD 100001 150000 ) & ( ./single_part_tab.sh $DU $DP $DD 150001 200000 ) & ( ./single_part_tab.sh $DU $DP $DD 200001 250000 ) & wait
J'ai lancé le tout hier (avec les plages de données de ce post) et le traitement a duré plus de 9 heures, pour seulement 250 000 enregistrements convertis en HTML, sachant que j'en ai 3 millions au final ça risque de prendre du temps, trop de temps.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 sqlplus -S $1/$2@$3 << EOF > logs/log_part_tab_$4_to_$5.log SET SERVEROUTPUT ON TIMING START mytimer_single_part_tab exec fast_way_byrange ($4,$5); TIMING STOP mytimer_part_tab exit EOF
Aussi, auriez vous des idées ? des conseils ? des corrections à apporter ? pour que ce traitement soit optimisé.
Et si vous voyez quelque chose de mauvais dans mon code merci d'avance pour vos précisions.
Merci d'avance
Partager