java操作mysql遇到大量数据会存在内存溢出的危险
分为两部分一个是java层方面,还有一个是mysql层
java
普通的方式
- 1.java发出请求,mysql响应
- 2.java获取数据的时候是不停地把缓冲区数据捞到内存中,一直到数据发送结束,等到所有数据获取完毕。我们客户端才能进一步操作,这就导致OOM
- 3.客户端只需要主动通信一次,剩余的都是服务器端主动推送数据
useCursorFetch
- 1.每次都要主动去请求指定大小的数据,这回导致通信频繁
- 2.当数据量很大的时候,为了避免长期占用索引数据,会把查询到的所有数据建立临时表
采用statement.setFetchSize(Integer.MIN_VALUE)并确保游标是只读向前滚动的即可(为游标的默认值),也可以强制类型转换为com.mysql.jdbc.StatementImpl,然后调用其内部方法:enableStreamingResults()这样读取数据内存就不会挂掉了
- 1.客户端只需要主动通信一次,剩余的都是服务器端主动推送数据
- 2.客户端每次只从buffer里面获取一部分数据即响应给业务,业务处理完成之后继续从buffer获取,服务端感受到客户端的buffer不满的时候会自动发送
Mysql层
单表查询mysql如何返回
- 1.客户端请求到了之后,server层让引擎层去执行,引擎层获取到一个记录后就立即发送给客户端
多表查询mysql如何返回
- 1.驱动表执行完毕一次之后会形成一个结果集,然后被驱动表会多次执行(执行次数就是驱动表的大小)每次取得一个完整记录也是立马发送
- 2.如果驱动表的结果集太大则会形成物化表(临时表,有基于内存的 如果再大则会变成B+树存储到磁盘)
总结
- 1.客户端采用stream方式最好,服务端则不用关心内存的问题
网友评论