J'ai une très grande table avec des millions d'enregistrements chaque jour et, à la fin de chaque journée, j'extrait tous les enregistrements de la veille. Voici comment je procède :
String SQL = "sélectionnez col1, col2, coln de ma table où timecol = hier"; Statement.executeQuery(SQL);
Le problème est que ce programme nécessite environ 2 Go de mémoire car il met tous les résultats en mémoire puis les traite.
J'ai essayé de définir Statement.setFetchSize(10)
mais il obtient exactement la même mémoire du système d'exploitation, aucune différence. J'utilise le pilote JDBC Microsoft SQL Server 2005
Existe-t-il un moyen de lire les résultats en petits morceaux comme le fait le pilote de base de données Oracle, en affichant seulement quelques lignes lorsque la requête est exécutée et davantage de résultats à mesure que vous faites défiler vers le bas ?
Dans JDBC, la méthode
setFetchSize(int)
est très importante pour la gestion des performances et de la mémoire au sein de la JVM, car elle contrôle le nombre d'appels réseau de la JVM vers la base de données et la quantité de données correspondante. RAM utilisée pour le traitement des jeux de résultats.Essentiellement, si setFetchSize(10) est appelé et que le pilote l'ignore, il n'y a que deux options possibles :
RESULT-SET est le nombre de lignes rassemblées sur la base de données en réponse à la requête. ROW-SET est le bloc de lignes extrait de RESULT-SET à chaque appel de la JVM vers la base de données. Le nombre de ces appels et la RAM requise pour le traitement dépendent du paramètre fetch-size.
Donc, si RESULT-SET a 100 lignes et que la taille de récupération est de 10, À tout moment, 10 appels réseau sont effectués pour récupérer toutes les données, en utilisant environ 10*{row-content-size} RAM.
La taille de récupération par défaut est de 10, ce qui est assez petit. Dans le cas publié, le pilote semble ignorer le paramètre de taille de récupération, récupérant toutes les données en un seul appel (nécessite beaucoup de RAM, un minimum d'appels réseau optimal).
Ce qui se passe sous
ResultSet.next()
, c'est qu'il n'obtient pas réellement une ligne à la fois du RESULT-SET. Il obtient ces données du ROW-SET (local) et obtient le prochain ROW-SET (invisible) du serveur lorsque les données sur le client local sont épuisées.Tout cela dépend du pilote, car la configuration n'est qu'un "indice", mais dans la pratique, j'ai constaté que c'est ainsi que fonctionnent de nombreux pilotes et bases de données (prouvé dans de nombreuses versions d'Oracle, DB2 et MySQL). p>