有什么办法,能以结构化数据的方式导出 MySQL 特定查询的数据,但是,不经过应用层级的内存?

2019-01-27 21:24:05 +08:00
 abcbuzhiming
经常会有这样的需求,请导出一个比较复杂的查询语句的结果,这个结果可能数量庞大,高达数十万甚至百万行。而导出结果的格式可能是 json,xml,或者 excel,无论哪一种,都必须把 mysql 的数据读入到编程语言开发的应用级程序中。然后在程序中进行结构化,再进行输出,应该数据量的庞大就面临着爆内存的问题。于是又必须回到分页查询结果的路上,但是分页查询某种程度上即加大了数据库的负担,而且速度严重的降低了。
我一直在考虑一个问题,理论上 mysql 自身读数据貌似是不需要太多额外的内存的,它仅仅是使用一个在其内部数据上移动的游标,基本可以理解为生成一行就丢一行到 IO 输出去,并不是把所有结果都累计起来然后丢出去。现在我的问题是,如何在 Java 应用层也实现这个目标呢
3079 次点击
所在节点    Java
10 条回复
gaoyulong
2019-01-27 21:35:04 +08:00
mysql 应该有类似的接口
ccpp132
2019-01-27 22:01:03 +08:00
使用 sax 接口的 json 库是否就行了
luozic
2019-01-27 22:06:39 +08:00
结构化就必须一次输出?不是可以后缀添加? 数据库也是默认分页的,不会一次输出好几千条数据。
jorneyr
2019-01-27 22:27:49 +08:00
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 的,其他的格式百度有。
karnaugh
2019-01-27 22:45:06 +08:00
老铁你这个头像有点涩啊 2333
night98
2019-01-27 23:50:49 +08:00
流式查询了解一下
des
2019-01-28 00:33:05 +08:00
用游标查,慢慢读
Trim21
2019-01-28 01:19:43 +08:00
用流式处理
buaacss
2019-01-28 08:14:58 +08:00
java 的 mysqlconnector 本身支持流式读取吧,迭代器就是一行行处理,具体到 connector 本身的实现应该是每次取 1000 行,遍历完了再取 1000 这样。处理成 csv 的话,内存里应该最多有 1000 行数据就够了,反正就是流式读取流式写入
sujin190
2019-01-28 09:42:04 +08:00
大部分 mysql driver 都实现了 nobuffer 的 cursor 了吧,execute 的并不会完成读取,只有真正读取行的时候才从 mysql 服务器读取,读完一行返回一行,然后直接写入文件就是了啊,不需要应用拥有大内存

不过似乎像 execl 好像不支持流式输出啊,坑死了,只能 csv

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/531077

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX