IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JDBC Java Discussion :

Performance requetes SQL/JDBC


Sujet :

JDBC Java

  1. #1
    Membre habitué

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Points : 182
    Points
    182
    Par défaut Performance requetes SQL/JDBC
    Bonjour

    N'étant pas un pro de requêtes SQL, ni de JDBC, je cherche à optimiser le temps pour l'insertion de requêtes SQL en base.
    J'ai une boucle sur un tableau d'entier qui contient des identifiants.

    j'ai simplifié mes requêtes pour une meilleure compréhension.

    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
     
    // boucle sur tous mes ids
    for(id : ids)
    {
     
      // je récupère un nouvel valeur pour l'insertion dans une table
      String sql_query = "SELECT S_AC_TRACE_LINK.nextval FROM dual";
      String NEXT_VAL = executeSelectQuery(sql_query);
     
     
      // 1ère insertion dans une table
      sql_query = "INSERT INTO AC_TRACE_LINK (DAT_ID_IN, LINK_ID) VALUES (id, NEXT_VAL)"; // j'utilise le id de la boucle et le NEXT_VAL
      executeQuery(sql_query);
     
     
      // 2ème insertion dans une table
      sql_query = "INSERT INTO AC_TRACE_CONF (LINK_ID, CONTEXT_ID) VALUES (NEXT_VAL, 39)"; // j'utilise le NEXT_VAL
      executeQuery(sql_query);
    }
     
    // executeSelectQuery
    public String executeSelectQuery(String sql_query)
    {
       // je simplifie
       connection = getConnection();
       statement = connection.createStatement();
       rs = statement.executeQuery(sql_query);
     
       return value;
    }
     
    // executeQuery
    public void executeQuery(String sql_query)
    {
       // je simplifie
       connection = getConnection();
       statement = connection.createStatement();
       statement.executeUpdate(sql_query);
    }
    Actuellement il y a 3 requêtes dans le corps de ma boucle qui, multiplié par le nombre de mes ids, fait énormément de requêtages en base.
    Y-a-t-il un moyen d'améliorer cela (du point de vue SQL et/ou du point de vue JDBC) ?
    j'ai vu qu'il y avait la méthode addBatch(sql) dans la classe Statement mais je ne pense pas que je puisse l'utiliser dans mon cas mais je peux me tromper.

    Merci de votre aide

  2. #2
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2009
    Messages
    354
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Juillet 2009
    Messages : 354
    Points : 593
    Points
    593
    Par défaut Réponse possible
    La solution du chef:

    Pourquoi ne pas créer des procédures stockées dans ta base de données et les appelées à chaque fois que tu en as besoin en leur passant les paramètres requis ?




    gain de temps considérable en production car les requêtes sont déjà compilées !

  3. #3
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Pour commencer avec des choses plus simple, il serait aussi pas mal de réutiliser la même connexion pour toute les requêtes car même avec le pooling ça a un impact.

    Ensuite il y a les preparedstatement, les batchs, etc...
    Sinon pour parler de performances pures, tu peux même faire une procédure stockée qui avale le tableau d'entier et fait tout le boulot en 1 seul appel JDBC.

  4. #4
    Membre habitué

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Points : 182
    Points
    182
    Par défaut
    Merci de vos réponses

    >Pourquoi ne pas créer des procédures stockées dans ta base de données et >les appelées à chaque fois que tu en as besoin en leur passant les paramètres >requis ?
    des procédures stockées, je ne sais pas ce que c'est, je vais regarder sur le net si je trouve des tutos/exemples

    >Ensuite il y a les preparedstatement, les batchs, etc...
    Je pense que ce n'est pas adapté à mon cas, car les 2 dernières requêtes de ma boucle dépend de la valeur retournée dans ma première requête, est-ce possible qd même de faire du batch?

  5. #5
    Expert éminent
    Avatar de _skip
    Homme Profil pro
    Développeur d'applications
    Inscrit en
    Novembre 2005
    Messages
    2 898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur d'applications
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 898
    Points : 7 752
    Points
    7 752
    Par défaut
    Non mais tu peux toujours récupérer toutes les nextval, et ensuite faire toutes les insertions nécessaires.

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 274
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 274
    Points : 4 141
    Points
    4 141
    Par défaut
    Tu n'es pas obligé de faire un select pour obtenir la valeur de ta séquence.
    Un S_AC_TRACE_LINK.nextval ou S_AC_TRACE_LINK.currval directement dans tes deux requêtes devrait suffire.

    L'intérêt des preparedstatement est d'avoir les requêtes déjà compilés au niveau de la base, et d'avoir seulement à changer les valeurs dynamiques.
    Donc oui, c'est bien de les utiliser.

    Et les batchs sont faits pour des insert/update par lots, donc oui, tu peux les utiliser.

  7. #7
    Membre habitué

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 106
    Points : 182
    Points
    182
    Par défaut
    Bonjour

    J'ai amélioré pas mal mon temps d'exécution en faisant des insertions multiples avec une seule requête.

    Maintenant, le temps que prends la boucle en faisant un "SELECT S_AC_TRACE_LINK.nextval FROM dual" pour récupérer une valeur de ma séquence prends plus de la moitié du temps d'exécution.
    Y-a-t-il moyen d'augmenter la rapidité?

    >Tu n'es pas obligé de faire un select pour obtenir la valeur de ta séquence.
    >Un S_AC_TRACE_LINK.nextval ou S_AC_TRACE_LINK.currval directement >dans tes deux requêtes devrait suffire.
    J'ai par réussi à les utiliser, je me prends une exception, si qqu'un a une solution pour que je puisse tester.



    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
     
    StringBuffer sqlBuffer1 = ...
    StringBuffer sqlBuffer2 = ...
     
    for(id : ids)
    {
     
      // je récupère un nouvel valeur pour l'insertion dans une table
      String sql_query = "SELECT S_AC_TRACE_LINK.nextval FROM dual";
      String NEXT_VAL = executeSelectQuery(sql_query);
     
     
      // 1ère insertion dans une table
      sqlBuffer1.append("INSERT ... "+NEXT_VAL); // j'ai simplifié ma requête pour une meilleure compréhension
     
      // 2ème insertion dans une autre table
      sqlBuffer2.append("INSERT ... "+NEXT_VAL);
    }
    //
    executeQuery(sqlBuffer1);
    //
    executeQuery(sqlBuffer2);

Discussions similaires

  1. Performance requete SQL
    Par cyclopsnet dans le forum SQL
    Réponses: 14
    Dernier message: 26/11/2010, 10h29
  2. Performance requete SQL
    Par billout9 dans le forum Oracle
    Réponses: 4
    Dernier message: 28/11/2005, 21h13
  3. [JDBC][SQL] Parser une requête SQL
    Par tomca dans le forum JDBC
    Réponses: 11
    Dernier message: 24/10/2005, 23h13
  4. [java/jdbc]SIMPLE REQUETE SQL: expression abssente
    Par b_52globemaster dans le forum JDBC
    Réponses: 6
    Dernier message: 16/08/2005, 11h38
  5. [JDBC] retour de requete sql avec valeur NULL
    Par maxxou dans le forum JDBC
    Réponses: 3
    Dernier message: 13/09/2004, 14h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo