2010-09-08 25 views
5

252759 tuples içeren bir tablom var. Hayatımı kolaylaştırmak için DataSet nesnesini kullanmak istiyorum, ancak tablom için bir DataSet oluşturmaya çalıştığımda, 3 saniye sonra java.lang.OutOfMemory alıyorum.Groovy sql veri kümesi java.lang.OutOfMemory neden olur

Veri kümeleriyle ilgili deneyimim yok, büyük tablolar için DataSet nesnesinin nasıl kullanılacağı konusunda yönergeler var mı?

cevap

1

JVM daha fazla bellek vermeyle neden başlamıyorsunuz?

java -Xms<initial heap size> -Xmx<maximum heap size> 

252759 tuples şey gibi 4GB RAM + bellekte başa çıkamayan bazı sanal bellek ile bir maching gelmiyor.

+0

Mükemmel şekilde verinin alınmasını kolaylaştırmak mümkün mü? Çünkü bellek artışı çok iyi ölçeklenmiyor. – Skarab

+0

Bunu yapmak isterseniz, normal JDBC'yi kullanmanız gerekir. Mükemmel bir şekilde, yani tüm sonucu bir arraylist olarak kopyalamak, tembel geri alma için uygun değildir, çünkü Groovy, temel sonuç kümesini kapatmak için ne zaman kaydedileceğini asla bilmeyebilir, çünkü listede açık close() yöntemi yoktur ; Bu nedenle, çöp toplama (bu kadar yakında gerçekleşmeyebilir) kadar açık bırakmak zorunda kalacak, böylece veritabanı sunucusunda kaynakları emecek. –

+0

Teşekkür ederim, DataSet API'sini anlamadım. Benim durumumda, tablodaki kayıtlar metinsel veriler içeriyor ve 4GB yeterli değil, bu yüzden JDBC'ye geri döneceğim. Zamanım varsa, Grails'in bir parçası olan GORM'e (Groovy ORM) de göz atmayı planlıyorum. – Skarab

7

Tüm satırları bir kerede almanız gerekiyor mu? Aksi takdirde, aşağıda gösterilen yaklaşımı kullanarak bunları (örneğin) 10000'lük gruplar halinde geri alabilirsiniz.

def db = [url:'jdbc:hsqldb:mem:testDB', user:'sa', password:'', driver:'org.hsqldb.jdbcDriver'] 

def sql = Sql.newInstance(db.url, db.user, db.password, db.driver) 
String query = "SELECT * FROM my_table WHERE id > ? ORDER BY id limit 10000" 

Integer maxId = 0 

// Closure that executes the query and returns true if some rows were processed 
Closure executeQuery = { 

    def oldMaxId = maxId 
    sql.eachRow(query, [maxId]) { row -> 

     // Code to process each row goes here..... 
     maxId = row.id 
    } 
    return maxId != oldMaxId 
} 


while (executeQuery()); 

AFAIK limit MySQL özgü bir özellik, ancak çoğu diğer RDBMS bir sorgu ile satır sayısını sınırlar eşdeğer bir özellik. Ayrıca, yukarıdaki kodu test etmedim (hatta derlemedim), bu yüzden dikkatle ele almayın!!

+0

Ham sql kullanmaktan kaçınmak için DataSet kullanmak istedim. – Skarab

+0

Bu yaklaşımı kullanmak istiyorsanız, 'Sql' kullanmalısınız. DataSet ile 'limit' gibi standart olmayan SQL özelliklerini kullanmak mümkün görünmüyor. –

+0

@Skarab: Genellikle, veritabanı sunucusundan çok fazla veriyi sql'den kaçınmak için işlem yapmak için kullanmak kötü bir fikirdir ... Bu veri, sadece uğraşmaktan çok daha yavaş olan ağ kablosu üzerinden gönderilmelidir. db sunucusunda. Dolayısıyla, aslında, böyle şeyler yaparak uygulamanıza potansiyel olarak sakat performans sorunları ekliyorsunuz. – NotMe

İlgili konular