MySQL golang驱动程序中的无缓冲结果集

cho*_*wey 5 mysql go

我有一个大型查询,我想使用Go MySQL驱动程序逐行处理结果.查询非常简单,但它返回了大量的行.

我见过mysql_use_result()vs mysqli_store_result()在C-API级别.是否存在通过TCP连接执行无缓冲查询的等效方法,例如Go MySQL驱动程序使用的方法?

Did*_*zia 6

数据库客户端库中缓冲/非缓冲查询的这一概念有点误导,因为实际上,缓冲可能发生在多个级别上.一般情况下(即不是Go特定的,而不是MySQL特定的),您有不同类型的缓冲区.

  • TCP套接字缓冲区.内核将通信缓冲区关联到每个套接字.默认情况下,此缓冲区的大小是动态的,并由内核参数控制.一些客户可以更改这些默认值以获得更多控制和优化.目的,如果此缓冲区用于管理设备队列中的流量,并最终减少网络上的数据包数量.

  • 通讯缓冲区.面向数据库的协议通常基于成帧协议,这意味着定义帧以分离TCP流中的逻辑分组.套接字缓冲区不保证完整的逻辑数据包(帧)可供读取.因此,需要额外的通信缓冲区以确保帧在处理时完整.它们还可以帮助减少系统调用次数.这些缓冲区由数据库客户端库的低级通信机制管理.

  • 行缓冲区.一些数据库客户端选择将从服务器读取的所有行保留在内存中,并让应用程序代码浏览相应的数据结构.例如,PostgreSQL C客户端(libpq)就是这样做的.MySQL C客户端将选择留给开发人员(通过调用mysql_use_result或mysql_store_result).

无论如何,你提到的Go驱动程序不是基于MySQL C客户端(它是纯粹的Go驱动程序).它仅使用两种第一种缓冲区(套接字和通信缓冲区).不提供行级缓冲.

每个MySQL连接有一个通信缓冲区.它的大小是4 KB的倍数.如果帧很大,它将动态增长.在MySQL协议中,每行作为单独的数据包(在帧中)发送,因此通信缓冲区的大小直接链接到客户端接收/发送的最大行.

结果是你可以运行一个返回大量行的查询而不会使内存饱和,并且仍然具有良好的套接字性能.使用此驱动程序,无论查询是什么,缓冲对于开发人员来说都不是问题.