作者:鲍凤其
爱可生 dble 团队开发成员,主要负责 dble 需求开发,故障排查和社区问题解答。少说废话,放码过来。
本文来源:原创投稿
*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。
背景
MySQL JDBC 在执行查询语句时,默认把查询的所有结果全部取回放在内存中,如果遍历很大的表,则可能把内存撑爆。
办法 1
查询语句中使用 limit,offset;这样我们会发现取数据的越来越慢,原因是在设置了 offset 之后,MySQL 需要将读取位置移动到 offset 的位置,随着 offset 增大,取数据也越来越慢;
办法 2
用数据流的方式取数据,可以指定 fetch size,这样每次获取指定数量的数据行,从而避免 OOM。此种方式的使用方式和原理可以参见文章:prepare statement 协议
第 2 种方式实际是 MySQL 中的 server-side 游标,server-side 游标是使用 MySQL 内部临时表来实现的。初始的时候,内部临时表是个内存表,当这个表的大小超过 max_heap_table_size and tmp_table_size 两个系统变量的最小值的时候(两者的最小值),会被转换成 MyISAM 表,即落盘存储。
内部临时表的使用限制同样适用于游标的内部临时表。
MySQL 中的两种临时表
外部临时表
用户通过 CREATE TEMPORARY TABLE 语句显式创建的临时表,这样的临时表称为外部临时表。
外部临时表生命周期:创建后,只在当前会话中可见,当前会话结束的时候,该临时表也会被自动关闭。
因此,两个会话可以存在同名的临时表,但若有同名的非临时表时,直到临时表被删除,这张表对用户是不可见的。

最低0.47元/天 解锁文章
510

被折叠的 条评论
为什么被折叠?



