This topic created in 2693 days ago, the information mentioned may be changed or developed.
经常会有这样的需求,请导出一个比较复杂的查询语句的结果,这个结果可能数量庞大,高达数十万甚至百万行。而导出结果的格式可能是 json,xml,或者 excel,无论哪一种,都必须把 mysql 的数据读入到编程语言开发的应用级程序中。然后在程序中进行结构化,再进行输出,应该数据量的庞大就面临着爆内存的问题。于是又必须回到分页查询结果的路上,但是分页查询某种程度上即加大了数据库的负担,而且速度严重的降低了。
我一直在考虑一个问题,理论上 mysql 自身读数据貌似是不需要太多额外的内存的,它仅仅是使用一个在其内部数据上移动的游标,基本可以理解为生成一行就丢一行到 IO 输出去,并不是把所有结果都累计起来然后丢出去。现在我的问题是,如何在 Java 应用层也实现这个目标呢
10 replies • 2019-01-28 09:42:04 +08:00
 |
|
2
ccpp132 Jan 27, 2019
使用 sax 接口的 json 库是否就行了
|
 |
|
3
luozic Jan 27, 2019 via iPhone
结构化就必须一次输出?不是可以后缀添加? 数据库也是默认分页的,不会一次输出好几千条数据。
|
 |
|
4
jorneyr Jan 27, 2019 1
SELECT * FROM demo WHERE id>2 ORDER BY id INTO OUTFILE '/Users/Biao/Desktop/a.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n';
这个是导出 csv 的,其他的格式百度有。
|
 |
|
5
karnaugh Jan 27, 2019
老铁你这个头像有点涩啊 2333
|
 |
|
7
des Jan 28, 2019 via Android
用游标查,慢慢读
|
 |
|
8
Trim21 Jan 28, 2019 via Android
用流式处理
|
 |
|
9
buaacss Jan 28, 2019
java 的 mysqlconnector 本身支持流式读取吧,迭代器就是一行行处理,具体到 connector 本身的实现应该是每次取 1000 行,遍历完了再取 1000 这样。处理成 csv 的话,内存里应该最多有 1000 行数据就够了,反正就是流式读取流式写入
|
 |
|
10
sujin190 Jan 28, 2019
大部分 mysql driver 都实现了 nobuffer 的 cursor 了吧,execute 的并不会完成读取,只有真正读取行的时候才从 mysql 服务器读取,读完一行返回一行,然后直接写入文件就是了啊,不需要应用拥有大内存
不过似乎像 execl 好像不支持流式输出啊,坑死了,只能 csv
|