我只需要使用Hibernate读取MySQL数据库中表中的每一行,并根据它编写一个文件.但是有9000万行,它们非常大.所以看起来以下是合适的:
ScrollableResults results = session.createQuery("SELECT person FROM Person person")
.setReadOnly(true).setCacheable(false).scroll(ScrollMode.FORWARD_ONLY);
while (results.next())
storeInFile(results.get()[0]);
Run Code Online (Sandbox Code Playgroud)
问题是上面将尝试将所有9000万行加载到RAM中,然后再转到while循环...这将使OutOfMemoryError消除我的内存:Java堆空间异常:(.
所以我猜ScrollableResults不是我想要的?处理这个问题的正确方法是什么?我不介意这个while循环需要几天(好吧我不喜欢它).
我想处理这个问题的另一种方法是使用setFirstResult和setMaxResults迭代结果,只使用常规的Hibernate结果而不是ScrollableResults.这感觉就像它效率低下一样,当我在8900万行中调用setFirstResult时,它将开始花费一段可笑的时间......
更新:setFirstResult/setMaxResults不起作用,事实证明需要花费相当长的时间才能达到我所担心的偏移量.这里一定有解决方案!这不是一个很标准的程序吗?我愿意放弃Hibernate并使用JDBC或其他任何东西.
更新2:我提出的解决方案哪个工作正常,不是很好,基本上是以下形式:
select * from person where id > <offset> and <other_conditions> limit 1
Run Code Online (Sandbox Code Playgroud)
由于我有其他条件,即使是索引中的所有条件,它仍然没有我想要的那么快......所以仍然可以提供其他建议..
我有一个实现Iterator的类,ResultSet作为数据成员.基本上这个类看起来像这样:
public class A implements Iterator{
private ResultSet entities;
...
public Object next(){
entities.next();
return new Entity(entities.getString...etc....)
}
public boolean hasNext(){
//what to do?
}
...
}
Run Code Online (Sandbox Code Playgroud)
如何检查ResultSet是否有另一行,以便我可以创建一个有效的hasNext方法,因为ResultSet没有自己定义hasNext?我正在考虑进行SELECT COUNT(*) FROM...查询以获取计数并管理该数字以查看是否有另一行但我想避免这种情况.
我正在尝试使用Spring和JdbcTemplate遍历MySQL中的每一行表.如果我没有弄错,这应该是这样简单:
JdbcTemplate template = new JdbcTemplate(datasource);
template.setFetchSize(1);
// template.setFetchSize(Integer.MIN_VALUE) does not work either
template.query("SELECT * FROM cdr", new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
System.out.println(rs.getString("src"));
}
});
Run Code Online (Sandbox Code Playgroud)
我得到一个OutOfMemoryError,因为它试图读取整个事情.有任何想法吗?
我目前正在尝试通过Spark SQL将非常大的MySQL表的内容批量迁移到镶木地板文件中.但是当这样做时,即使将驱动程序的内存限制设置得更高(我在本地模式下使用spark),我也会快速耗尽内存.示例代码:
Dataset<Row> ds = spark.read()
.format("jdbc")
.option("url", url)
.option("driver", "com.mysql.jdbc.Driver")
.option("dbtable", "bigdatatable")
.option("user", "root")
.option("password", "foobar")
.load();
ds.write().mode(SaveMode.Append).parquet("data/bigdatatable");
Run Code Online (Sandbox Code Playgroud)
似乎Spark试图将整个表内容读入内存,这样做不会很好.那么,通过Spark SQL进行批量数据迁移的最佳方法是什么?
我在尝试进行大查询时收到此错误.
java.lang.OutOfMemoryError: Java heap space
Run Code Online (Sandbox Code Playgroud)
我搜索并发现将setAutoCommit(false)和setFetchSize方法应用于我准备好的语句可能有助于处理大查询.但是,当我使用它时,我收到了这个错误.
java.sql.SQLException: Illegal value for setFetchDirection().
Run Code Online (Sandbox Code Playgroud)
处理大型查询的正确方法是什么?
使用setFetchSize的正确方法是什么?
我有包含 1600 万条记录的 MySql 表,由于一些迁移工作,我正在读取整个 Mysql 表。
以下代码用于在 MySql 中流式传输大型 ResultSet
statement = connection.createStatement(
java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
statement.setFetchSize(Integer.MIN_VALUE);
Run Code Online (Sandbox Code Playgroud)
但这是一次流式传输一个结果,这是否意味着我们正在为每一行访问 MySql 服务器
在使用流式传输时,我们可以设置类似这样的语句:setFetchSize(1000);
我想在流式传输大型结果集时减少到服务器的往返次数
我需要另外一双眼睛看这个。
我已经用这个确切的代码将一个 zip 文件写成数百 GB,在 MacOSX 上没有本地修改。
使用 100% 未更改的代码,只是部署到运行 Ubuntu 的 AWS 实例,同样的代码会遇到内存不足问题(堆空间)。
这是正在运行的代码,将 MyBatis 流式传输到磁盘上的 CSV 文件:
File directory = new File(feedDirectory);
File file;
try {
file = File.createTempFile(("feed-" + providerCode + "-"), ".csv", directory);
} catch (IOException e) {
throw new RuntimeException("Unable to create file to write feed to disk: " + e.getMessage(), e);
}
String filePath = file.getAbsolutePath();
log.info(String.format("File name for %s feed is %s", providerCode, filePath));
// output file
try (FileOutputStream out = new FileOutputStream(file)) …Run Code Online (Sandbox Code Playgroud) 我有一个包含 800 万条记录的数据库,我需要以特定方式处理这些记录,这些记录是用 Java 编写的。在查找了一些东西后,我发现了以下相关帖子:
这是我的代码,它返回存储在我的 MySQL 数据库的标签列中的项目:
public ResultSet getAllTags() {
String query = "SELECT Tags FROM dataset";
ResultSet rs = null;
try {
connection = ConnectionFactory.getConnection(DATABASE);
preparedStatement = connection.prepareStatement(query, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
preparedStatement.setFetchSize(Integer.MIN_VALUE);
rs = preparedStatement.executeQuery(query);
// following line is for testing, to see what comes out of the resultset
System.out.println("output: " + rs.getString(1));
return rs;
} catch (Exception ex) {
ex.printStackTrace();
return null;
} finally {
closeAll();
} …Run Code Online (Sandbox Code Playgroud) 有一个表phonenumbers有两列:id和number.有大约half a million entries在表中.数据库是MySQL.
要求是开发一个连接到该数据库的简单Java EE应用程序,允许用户通过遵循特定URL 下载所有number值comma separated style.
如果我们得到一个巨大的所有值,String array然后在a中连接它们(在所有值之间使用逗号)String然后将其发送给用户,它听起来是一个合适的解决方案吗?
该申请不公开,将由有限的号码使用.人
java ×8
mysql ×6
jdbc ×3
sql ×3
heap-memory ×2
memory-leaks ×2
apache-spark ×1
hibernate ×1
iterator ×1
java-ee ×1
large-query ×1
memory ×1
resultset ×1
spring ×1