[java] Problème d'optimisation de traitements batch

Problème d'optimisation de traitements batch [java] - Java - Programmation

Marsh Posté le 06-07-2009 à 11:13:37    

Bonjour,
 
J'ai un problème au niveau de l'optimisation de mon code Java de mes requêtes, en fait voici comme je procède :  
 
- Récupération d'environ 100 000 indentifiants de publications.
- je crée un batch de 100 publications pour récupérer le contenue des publications via un web service (l'auteur, le titre etc...)
- je passe les 100 publications par une 20aine de méthodes (toutes les tables correspondants à ma base de données), pour les insérer en base locale.
 
Mon problème se situe au niveau de l'insertion en base des 100 publications, je met trop de temps à ce niveau là. Je suis plus ou moins ce schéma là :
- Création d'une connexion
- appel des méthodes avec en paramètre la liste de publication et la connexion
Pour chaque méthode qui correspond à chaque table je fait
 création d'un preparedstatement de batch, je parcours la liste de publication et selon la table je vérifie si l'information est déjà présente en base, dans le cas contraire j'ajoute la ligne en batch et en fin de boucle j'exécute le batch
- à la fin des méthodes d'insertion je ferme ma connexion.
 
Cette étape prend trop de temps, je vois pas comment l'optimiser, quelqu'un aurait une idée ?  
 
Merci d'avance :) !


Message édité par Subgenk le 06-07-2009 à 13:23:32
Reply

Marsh Posté le 06-07-2009 à 11:13:37   

Reply

Marsh Posté le 06-07-2009 à 12:14:19    

Quand tu crée ta connection, fait un connection.setAutoCommit(false); et à la fin de ton traitement, avant ton connection.close(), fais un connect.commit(); Ca devrait déjà faire gagner pas mal de temps

Reply

Marsh Posté le 06-07-2009 à 12:26:54    

ça fait quoi exactement ?

Reply

Marsh Posté le 06-07-2009 à 13:32:54    

L'autocommit fait faire un commit après chaque update/insert/delete.
 
Le commit en lui même permet de dire, en très gros, à la base de donnée, que l'action que les actions qu'on a effectué depuis le dernier commit sont a prendre EFFECTIVEMENT en compte.
 
Je pense qu'une petite recherche Google sera plus claire et plus efficace que moi ;)

Reply

Marsh Posté le 07-07-2009 à 10:55:07    

L'idée d'une transaction en base de données, c'est que tu veux:
-avoir une base dans un état cohérent avant la transaction
-avoir une base dans un état cohérent après la transaction

 

une transaction, c'est
-une prise de verrou sur la base
-une série de requêtes
-un commit ou un rollback

 

Pour ça, tu définis toutes tes requêtes et quand tu es sûr que toutes tes requêtes ont été prises en compte (et qu'après celle-ci, tu es dans un état cohérent), tu fais un commit pour les appliquer effectivement.

 

Si une erreur se produit alors que tu n'as pas passé toutes tes requêtes, au lieu de faire un commit, tu peux faire un rollback et ainsi annuler toute la série de requête et revenir dans un état cohérent de la base (l'état dans lequel tu étais avant de passer ta première requête).

 

en mode auto-commit, si je dis pas de bêtises (mais reprenez moi parce que je suis pas expert en base de données) ça va, pour chaque requête:
-prendre un verrou sur la base de données
-jouer la requête
-faire un commit
-lâcher le verrou sur la base de données

 

donc si t'as 100 000 requêtes, tu prends 100 000 fois le verrou sur la base de données et ça, c'est très couteux.

 

Voili, j'espère avoir fourni une explication claire (et pas trop fausse :D)


Message édité par liouan le 07-07-2009 à 17:12:44
Reply

Marsh Posté le 07-07-2009 à 11:01:13    

liouan explique beaucoup mieux que moi.
 
L'idée pour optimiser le traitement, c'est déjà de bannir l'autocommit, sauf si tu peux pas faire autrement (Par exemple si ta base ne gère pas les transaction, comme Mysql avec un moteur MyIsam si je ne dis pas de bétises. Il vaut mieux dans ce cas passer à un moteur InnoDb ou le prochain MariaDb)


Message édité par john-bob le 07-07-2009 à 11:04:31
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed