web-dev-qa-db-fra.com

Est-ce qu'un ResultSet charge toutes les données en mémoire ou seulement à la demande?

J'ai une page .jsp où j'ai une table graphique qui affiche les enregistrements d'une base de données Oracle. Ce tableau permet un comportement de pagination typique, tel que "PREMIER", "SUIVANT", "PRÉCÉDENT" et "LAST". Les enregistrements sont obtenus à partir d'un objet Java ResultSet renvoyé à partir de l'exécution d'une instruction SQL.

Ce ResultSet peut être très gros, alors ma question est:

Si j'ai un ResultSet contenant un million d'enregistrements mais que ma table affiche uniquement les données des dix premiers enregistrements du ResultSet, les données sont-elles récupérées uniquement lorsque je commence à demander des données d'enregistrement ou toutes les données sont-elles entièrement chargées en mémoire une fois que le ResultSet est renvoyé à partir de l'exécution d'une instruction SQL?

33
tth

Le Java ResultSet est un pointeur (ou curseur) sur les résultats de la base de données. ResultSet charge les enregistrements par blocs de la base de données. Donc, pour répondre à votre question, les données ne sont récupérées que lorsque vous le demandez, mais par blocs.

Si vous devez contrôler le nombre de lignes lues en même temps par le pilote, vous pouvez utiliser la méthode setFetchSize () sur le ResultSet. Cela vous permettra de contrôler la taille des blocs récupérés en une fois.

39
Chris Dail

La spécification JDBC ne spécifie pas si les données sont diffusées ou si elles sont chargées en mémoire. Oracle diffuse par défaut. MySQL ne le fait pas. Pour que MySQL transmette le résultat en streaming, vous devez définir les éléments suivants dans la déclaration:

    pstmt = conn.prepareStatement(
        sql,
        ResultSet.TYPE_FORWARD_ONLY,
        ResultSet.CONCUR_READ_ONLY);
    pstmt.setFetchSize(Integer.MIN_VALUE);
10
Joshua

Bien que la spécification JDBC ne spécifie pas si toutes les données du jeu de résultats doivent être extraites, aucun pilote bien écrit ne le fera.

Cela dit, un ensemble de résultats à défilement pourrait correspondre davantage à ce que vous avez en tête: (Lien rédigé, il pointe vers une page de logiciel espion)

Vous pouvez également envisager un ensemble de lignes déconnectées, qui est stocké dans la session (en fonction de la capacité d'évolution de votre site): http://Java.Sun.com/j2se/1.4.2/docs /api/javax/sql/RowSet.html

1

La meilleure idée est de créer une sous-requête et d’afficher 100 ou 1000 lignes à la fois/sur une seule page. Et gérer la connexion par pool de connexions.

Pour créer une sous-requête, vous pouvez utiliser le nombre de lignes dans Oracle et la limite dans MY SQL.

0
Tony

disons que nous avons une table qui contient 500 enregistrements

PreparedStatement stm=con.prepareStatement("select * from table");
stm.setFetchSize(100);// now each 100 records are loaded together from the database into the memory,
// and since we have 500 5 server round trips will occur.
ResultSet rs = stm.executeQuery();
rs.setFetchSize (50);//overrides the fetch size provided in the statements,
//and the next trip to the database will fetch the records based on the new fetch size
0
QuakeCore