comment puis-je charger de 100 millions de lignes à la mémoire

J'ai la nécessité de chargement de 100 millions d'+ lignes à partir d'une base de données MySQL pour la mémoire. Mon programme java échoue avec java.lang.OutOfMemoryError: Java heap space
J'ai 8 go de RAM sur ma machine et j'ai donné des -Xmx6144m dans mes options JVM.

C'est mon code

public List<Record> loadTrainingDataSet() {

    ArrayList<Record> records = new ArrayList<Record>();
    try {
        Statement s = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY, java.sql.ResultSet.CONCUR_READ_ONLY);
        s.executeQuery("SELECT movie_id,customer_id,rating FROM ratings");
        ResultSet rs = s.getResultSet();
        int count = 0;
        while (rs.next()) {

Une idée de comment résoudre ce problème?


Mise à JOUR

Je suis tombé sur ce post, ainsi que sur la base des commentaires ci-dessous j'ai mis à jour mon code. Il semble que je suis en mesure de charger les données dans la mémoire avec la même Xmx6144m montant, mais il prend beaucoup de temps.

Voici mon code.

...
import org.apache.mahout.math.SparseMatrix;
...
@Override
public SparseMatrix loadTrainingDataSet() {
long t1 = System.currentTimeMillis();
SparseMatrix ratings = new SparseMatrix(NUM_ROWS,NUM_COLS);
int REC_START = 0;
int REC_END = 0;
try {
for (int i = 1; i <= 101; i++) {
long t11 = System.currentTimeMillis();
REC_END = 1000000 * i;
Statement s = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
s.setFetchSize(Integer.MIN_VALUE);
ResultSet rs = s.executeQuery("SELECT movie_id,customer_id,rating FROM ratings LIMIT " + REC_START + "," + REC_END);//100480507
while (rs.next()) {
int movieId = rs.getInt("movie_id");
int customerId = rs.getInt("customer_id");
byte rating = (byte) rs.getInt("rating");
ratings.set(customerId,movieId,rating);
}
long t22 = System.currentTimeMillis();
System.out.println("Round " + i + " completed " + (t22 - t11) / 1000 + " seconds");
rs.close();
s.close();
}
} catch (Exception e) {
System.err.println("Cannot connect to database server " + e);
} finally {
if (conn != null) {
try {
conn.close();
System.out.println("Database connection terminated");
} catch (Exception e) { /* ignore close errors */ }
}
}
long t2 = System.currentTimeMillis();
System.out.println(" Took " + (t2 - t1) / 1000 + " seconds");
return ratings;
}

Charge les premiers 100 000 lignes il a fallu 2 secondes. Pour charger 29 100 000 lignes il a fallu 46 secondes. J'ai arrêté le processus dans le milieu car il prenait trop de temps. Sont-elles acceptables quantités de temps? Est-il un moyen pour améliorer les performances de ce code?
Je suis en cours d'exécution ce sur 8GO de RAM 64 bits de windows de la machine.

Pourquoi voudriez-vous peut-être besoin de toutes à la fois? Mettre en œuvre une sorte de pagination sur le côté de la base de données, et de les amener dans les morceaux que vous en avez besoin.
Quel est le besoin?
Pas sûr de ce que votre objectif est, mais Vous pouvez également faire usage de lucene.apache.org/solr pour charger et vous pouvez écrire jasper etc sur le haut et il sera beaucoup plus rapide et efficace qu'une interaction directe avec la DB.
Veuillez expliquer la nécessité. Pourquoi iriez-vous au hasard?
Une ArrayList est un mauvais choix quand on travaille avec de très grands ensembles de données. Une liste de tableau initialisé avec son constructeur par défaut - infiniment pire. Mais même si vous passez à droite de la matrice de vous allez avoir des problèmes de côté toutes les données principales de la mémoire à la fois.

OriginalL'auteur ravindrab | 2013-01-26