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)
1 2 3 4 5 6 7 8 9
| 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:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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?