jdbc通信原理
一、普通查询默认行为正确流程JDBC客户端通过Socket与MySQL服务器建立TCP连接。客户端发送SQL查询语句。MySQL服务器执行查询将结果集数据从存储引擎读出放入服务器内核的发送缓冲区位于操作系统内核空间。服务器内核通过TCP协议将数据分段经网络传输到客户端机器。数据到达客户端网卡后由内核放入客户端内核的接收缓冲区即Socket缓冲区位于内核空间。JDBC驱动执行read()系统调用从该内核缓冲区读取数据到驱动内部缓冲区用户空间可选再复制到JVM堆内存中的对象如ResultSet的行缓存。默认情况下JDBC驱动会一直读取直到所有数据到达executeQuery()才返回ResultSet对象。这意味着所有结果集数据都已加载到JVM内存中。二、游标查询Cursor Query正确描述定义MySQL的游标查询通过在连接URL中添加useCursorFetchtrue并设置fetchSize来启用。它使用服务器端游标materialized cursor服务器将结果集暂存于临时表或内存中客户端多次主动FETCH获取数据。流程客户端发送查询MySQL服务器创建游标并将结果集物化写入临时文件或内存表。服务器只返回第一行或第一批数据由fetchSize决定而不是全部结果。客户端每次调用rs.next()当本地缓存用完时驱动自动发送FETCH命令获取下一批。服务器从临时存储中读取下一批数据返回。资源开销服务器端需要额外的磁盘I/O或内存来存储完整结果集尤其是大结果集并维护游标状态。网络多次往返交互每批一次请求-响应。客户端内存中只保留当前批次避免OOM。三、流式查询Streaming Query正确描述定义流式查询指服务器边生成结果边发送无需物化完整结果集客户端以流的方式持续接收。不同数据库实现不同PostgreSQL设置fetchSize后使用协议级别的“门户”实现真正的流式服务器无状态数据边查边发。MySQL实际上并没有真正的流式查询其“流式”是通过游标模拟的服务器端仍需物化但客户端分批拉取。MySQL官方文档中提到的“流式”通常指设置fetchSize为Integer.MIN_VALUE旧版本或使用游标。流程以PostgreSQL为例客户端发送查询并指定fetchSize。服务器开始执行查询每生成一批数据例如100行就立即通过TCP连接发送给客户端。客户端驱动接收数据并放入JVM应用程序通过rs.next()消费。服务器继续生成下一批并发送直到全部发完。特点服务器无需物化完整结果集节省I/O和内存。网络通信为“推”模式一次请求多次响应。客户端处理速度可能影响服务器发送如果客户端读取慢TCP滑动窗口会反压服务器导致服务器阻塞发送缓冲区满。五、总结与建议普通查询适合小结果集简单高效大结果集必须改用游标/流式。MySQL用户使用useCursorFetchtrue fetchSize实现游标查询注意服务器额外I/O开销。PostgreSQL用户直接设置fetchSize即可获得真正的流式体验。设计考虑如果数据量极大且服务器资源紧张流式无物化更优如果需要精确控制分批且数据库支持游标游标查询也足够。希望这份优化后的笔记能帮你理清概念。如果还有疑问欢迎继续探讨
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2418849.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!