我试图创建一个Java程序来清理和我的表行合并。 表很大,大约50万行和我目前的解决方案是运行速度非常慢。 我想做的第一件事是简单地得到一个内存阵列代表我的表中的所有行对象。 下面是我在做什么:
- 挑说的增量1000行同时
- 使用JDBC上下面的SQL查询取一个结果SELECT * FROM TABLE WHERE ID> 0 AND ID <1000
- 所得到的数据添加到一个内存阵列
- 继续查询一路攀升至50万1000个增量,每次加的结果。
这是采取的方式长。 事实上它甚至没有获得过第二增量从1000到2000年的查询需要永远结束(虽然当我直接通过MySQL的浏览器上运行同样的事情,它的体面快)。 它因为我已经直接使用JDBC一段时间。 是否有一个更快的替代方案?
首先,你确定你需要整个表的记忆? 也许你应该考虑(如果可能的话)选择您要更新/合并/等行。 如果你真的要有整个表,你可以考虑使用一个滚动的ResultSet。 你可以这样创建它。
// make sure autocommit is off (postgres)
con.setAutoCommit(false);
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, //or ResultSet.TYPE_FORWARD_ONLY
ResultSet.CONCUR_READ_ONLY);
ResultSet srs = stmt.executeQuery("select * from ...");
它使您能够使用“绝对”和“相对”的方法来移动到任何你想要的行。
虽然它可能不是最佳的,你的解决方案看起来像它应该为一次性数据库清理程序被罚款。 它不应该花这么长时间来运行这样一个查询,得到的结果(我假设,因为它是一次性的几秒钟就可以了)。 可能出现的问题 -
如果你没有通过第二增量得到的东西是真的错了 - 高效与否,你不应该有倾倒2000,或20,000行到内存上运行的JVM的任何问题。 也许你冗余或低效极存储数据?
有一两件事让我很Statement.setFetchSize(Integer.MIN_VALUE)
。 我从这个想法Jason的博客 。 这一半以上减少执行时间。 消耗的内存就大幅下降(因为只有一个行一次读取。)
这招不适合工作PreparedStatement
,虽然。