Hello, I wrote a simple case in order to reproduce the problem (doesn't do
any cleanup).
In the test scenario, the OOM will always happen, when H2 is running the
group by query on a table with 5 million rows.
What would be the cause? Memory options for the JVM in the test scenario,
during my testing were -XmX1024m.
void createTablesForGroupByScenario() throws SQLException {
String dir = "/path/to/some/dir";
Integer[] sizes = new Integer[] { 1000, 10_000, 100_000, 1_000_000,
5_000_000 };
for (Integer size : sizes) {
System.out.println("Creating table with size: " + size);
String name = "group_by_" + size;
String h2Url = "jdbc:h2:file:" + dir + "/" + name
+ ";DB_CLOSE_ON_EXIT=FALSE"
+ ";AUTO_RECONNECT=TRUE"
+ ";FILE_LOCK=NO"
+ ";TRACE_LEVEL_FILE=0"
+ ";TRACE_LEVEL_SYSTEM_OUT=0"
+ ";LOG=0"
+ ";UNDO_LOG=0"
+ ";CACHE_SIZE=" + 65000;
Connection con = DriverManager.getConnection(h2Url);
String initSql = "create table result(id bigint, name varchar,
phone int);\n";
RunScript.execute(con, new StringReader(initSql));
con.commit();
PreparedStatement st = con.prepareStatement("insert into result
values (?, ?, ?)");
for (int i = 0; i < size; i++) {
st.setLong(1, i);
st.setString(2, "name_" + i);
st.setInt(3, i);
st.addBatch();
if (i % 500 == 0) {
st.executeBatch();
con.commit();
}
}
st.executeBatch();
con.commit();
con.close();
}
}
void forEveryDbCreatedRunGroupByQuery() throws SQLException {
String dir = "/path/to/some/dir";
Integer[] sizes = new Integer[] { 1000, 10_000, 100_000, 1_000_000,
5_000_000 };
for (Integer size : sizes) {
System.out.println("Running query for table with size: " + size
);
String name = "group_by_" + size;
String h2Url = "jdbc:h2:file:" + dir + "/" + name
+ ";DB_CLOSE_ON_EXIT=FALSE"
+ ";AUTO_RECONNECT=TRUE"
+ ";FILE_LOCK=NO"
+ ";TRACE_LEVEL_FILE=0"
+ ";TRACE_LEVEL_SYSTEM_OUT=0"
+ ";LOG=0"
+ ";UNDO_LOG=0"
+ ";CACHE_SIZE=" + 65000;
Connection con = DriverManager.getConnection(h2Url);
String sql = "select id, sum(phone) from result group by id;\n";
long start = System.currentTimeMillis();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
int processed = 0;
while (rs.next()) {
//'fake' result-set processing by just counting the results
processed++;
}
con.close();
long time = System.currentTimeMillis() - start;
System.out.println(String.format("Processed %s, time %s ms",
processed, time));
}
}
--
You received this message because you are subscribed to the Google Groups "H2
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/h2-database/07c5cd18-4c99-497b-a30d-7fab2abcfbba%40googlegroups.com.