I have this simple table, with lots of rows (well… about 400.000) with less than 100 bytes per row.
So I connect to the database, create a Statement, and call Statement.executeQuery(String)
public static void main(String[] args) throws Exception
{
Class.forName("com.mysql.jdbc.Driver");
java.sql.Connection con = DriverManager.getConnection(args[0], args[1], args[2]);
String sql = "SELECT `id` FROM `SomeTable` WHERE `something` <> 'something else'";
Statement stmt = sqlCon.createStatement();
stmt.setFetchSize(64);
ResultSet result = stmt.executeQuery(sql);
}
After a few seconds, I get the infamous OOME:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.mysql.jdbc.Buffer.getBytes(Buffer.java:198)
at com.mysql.jdbc.Buffer.readLenByteArray(Buffer.java:318)
at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1375)
at com.mysql.jdbc.MysqlIO.readSingleRowSet(MysqlIO.java:2369)
at com.mysql.jdbc.MysqlIO.getResultSet(MysqlIO.java:451)
at com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(MysqlIO.java:2076)
at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:1451)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1787)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3277)
at com.mysql.jdbc.Connection.execSQL(Connection.java:3206)
at com.mysql.jdbc.Statement.executeQuery(Statement.java:1232)
at touchetracks.Launcher.main(Launcher.java:16)
As you can see, the code crashes at executeQuery(…) so I’m not even travering the ResultSet.
It seems like it’s loading all rows into RAM, before returning.
When I add a condition, to reduce the amount of rows in the ResultSet, the problem goes away - but I need almost the whole table in this case.
Can anybody be kind enough to point me at the obvious thing I forgot?