Salut !
Je dois lire un fichier texte dont les lignes correspondent à des enregistrements à insérer en base. Le fichier est de la forme :
chp1,1~chp1,2~chp1,3~.....
chp2,1~chp2,2~chp2,3~.....
chp3,1 ..
....
Or ce fichier fait 3Go !
Je dispose certes d'un gros serveur et d'une base Oracle avec le driver jdbc qui va bien. Mais j'aimerais que le traitement ne prenne pas plus de 20 heures.
Dans un premier temps mon souci est de parcourir le fichier le plus rapidement possible et de spliter la chaîne pour construire ma requête.
Voici les deux méthodes que j'ai essayées sur un fichier de 5 Mo sur ma vieille bécane (Athlon 2400+, 512 Mo de RAM, OS Ubuntu). La 1ère semble plus performante mais de peu.
(Précisions pour que vous ne vous demandiez pas ce que je trafique dans mon code : la valeur du champ id servant de clé primaire doit être : ChpCle1 + "_" + ChpCle2)
1ère méthode :
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
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 public static void lire1(String fic) { try { java.util.Date d1 = new java.util.Date(); String[] libelleChps = new String[7]; libelleChps[0] = "id"; libelleChps[1] = "ChpCle1"; libelleChps[2] = "ChpCle2"; libelleChps[3] = "chp1"; libelleChps[4] = "chp2"; libelleChps[5] = "chp3"; libelleChps[6] = "chp4"; FileReader fr = new FileReader(fic); BufferedReader br = new BufferedReader(fr); String ligne = br.readLine(); while (ligne != null){ String[] tab = ligne.split("~"); String req = "INSERT INTO data (id"; String val = " VALUES ('" + tab[0] + "_" + tab[1] + "'"; for (int i = 0; i < tab.length; i++){ req += "," + libelleChps[i+1]; val += ",'" + tab[i] + "'"; } req = req + ")" + val + ")"; System.out.println(req); ligne = br.readLine(); } br.close(); fr.close(); java.util.Date d2 = new java.util.Date(); double tps = d2.getTime() - d1.getTime(); System.out.println("MILLISECONDES : " + tps); System.out.println("SECONDES : " + (tps/1000)); } catch (Exception e) { e.printStackTrace(); } }
2ème métode :
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
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 public static void lire2(String fic) { try { java.util.Date d1 = new java.util.Date(); String[] libelleChps = new String[7]; libelleChps[0] = "id"; libelleChps[1] = "ChpCle1"; libelleChps[2] = "ChpCle2"; libelleChps[3] = "chp1"; libelleChps[4] = "chp2"; libelleChps[5] = "chp3"; libelleChps[6] = "chp4"; FileReader fr = new FileReader(fic); int carac = 0; char delimiter = '\n'; String chaine = ""; carac = fr.read(); while (carac != -1) { chaine = ""; while (carac != (int)delimiter && carac != -1) { chaine += (char) carac; carac = fr.read(); } String[] tab = chaine.split("~"); String req = "INSERT INTO data (id"; String val = " VALUES ('" + tab[0] + "_" + tab[1] + "'"; for (int j = 0; j < tab.length; j++) { req += "," + libelleChps[j+1]; val += ",'" + tab[j] + "'"; } req += ")" + val + ")"; System.out.println("SQL = " + req); carac = fr.read(); } fr.close(); java.util.Date d2 = new java.util.Date(); double tps = d2.getTime() - d1.getTime(); System.out.println("MILLISECONDES : " + tps); System.out.println("SECONDES : " + (tps/1000)); } catch (Exception e) { e.printStackTrace(); } }
Selon vous quelle est la méthode la plus rapide ? Y-a-t-il plus rapide en Java ?
PS : Les contrôles et logs erreurs que je dois gérer ne me permettent pas d'utiliser un outil comme SQLLoader.
Merci d'avance pour vos réponses éclairées
Partager