Optimiser ses requêtes JDBC en java

Lorsque vous utilisez un driver JDBC Java, le ResultSet vous permettant de récupérer chaque ligne retournée par votre requête peut être lent. Le ResultSet pour certain driver ne retourne qu’une ligne à la fois, si la connexion entre votre serveur web et votre base de données est lente, vos requêtes vont s’en trouver ralentit. En effet, chaque ligne retourné par votre SELECT et récupéré par le ResultSet correspond à un appel à votre base de donnée.

Pour résoudre d’éventuels problèmes de lenteur, il est possible de définir le nombre de ligne retournée. Par défaut, votre Statement ou PreparedStatement ne retourne qu’une ligne en la fois.Lors du parcours du ResultSet, cela peut s’avérer catastrophiquepour vos performances.

Utilisez la méthode setFetchSize sur votre object Statement afin de définir le nombre de ligne à ramener à chaque appel à la base de donné.

Connection cnx = ConnexionOracle.getConnexion(true);
Statement stmt = cnx.createStatement();
stmt.setFetchSize(500);

Ce code ramène les lignes demandées par paquet de 500 lignes (Ne pas confondre avec l’ordre LIMIT qui n’a rien à voir)

Attention, ne devenez pas accro à cette méthode. Elle peut s’avérer très vite gourmande en ressource. Cette méthode s’applique à un Statement ou PreparedStatement. Par définition,elle peut donc être défint pour chaque requête. Adapter donc le fetchSize en fonction du nombre de lignes retournées par vos requêtes. Il serait idiot de définir un FetchSize de 500 pour une requête qui ne ramène qu’un count d’une table( et par conséquent une seule ligne).

De plus, il est à noté que certains drivers ignorent complétement cette instruction et utilise leurs propres systèmes d’optimisation.

3 réflexions au sujet de « Optimiser ses requêtes JDBC en java »

  1. Je voulais savoir s’il y a des articles qui parlent aussi sur l’amélioration du performance des requêtes pour le JDBC.merci pour votre aide

  2. J’ai essayé avec setfetchsize mais j’obtient rien , le temp c’est 240ms ce qu’il me parait faux car je travaille avec des millions des enregistrements:

    try {
    Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@//host:port/db", "chunk2", "chunk2");
    System.out.println("cnx bien établie!");
    conn.setAutoCommit(false);
    long begin = System.currentTimeMillis();
    Statement stm = conn.createStatement();
    stm.setFetchSize(1000);
    ResultSet rs = stm.executeQuery("SELECT objectid from object ");
    system.out.println( System.currentTimeMillis() - begin);
    } catch (Exception e) {
    System.out.println("exception");
    }

  3. C’est normal que le temps soit très rapide, ton code ne ramène aucune ligne pour le moment. Il faut faire appel à la méthode next() du ResultSet pour que les lignes soient vraiment « demandées » à Oracle. la méthode executeQuery() ne fait que demander l’exécution de la requête à Oracle, mais les lignes ne sont pas ramenés
    Essaye d’ajouter while(rs.next()){} et tu devrait un avoir un temps d’exécution plus conséquent.

    Ce n’est qu’à l’appel de la méthode next() que FetchSize est pris en compte, au lieu de ramener les lignes une par une, ton driver jdbc va en demander 1000 d’un coup et les mettre en cache pour les prochains appels à next(). Cela permet de faire qu’un appel réseau toute les 1000 lignes, cet qu’il est considérablement plus rapide que d’effectuer 1000 requêtes sur le réseau (surtout si la base est éloigné physiquement)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.