mysql 一次性 select 一千万条会导致oom吗?
假设表里有 1千万条数据,使用 gorm 去获取全部数据,执行如下代码
rows, err := gormDb.Raw("select * from xxx_table").Rows()
if err != nil {
panic(err)
}
for rows.Next() {
}
问题一:
执行 gormDb.Raw("select * from xxx_table").Rows()
,会把数据库所有数据加载到内存吗?经过跟踪源码好像是执行 rows.Next 时才会从 tcp 链接中读取一条数据,如果是这样的 go 服务应该不会有 oom 的风险,但是我不太理解这个读取结果是存到了什么地方,是 go 服务 net.Read 的时候 mysql 才会向 tcp 发结果数据吗?(流式处理)
问题二:
一次性查那么多条数据,mysql 服务是怎么处理的,是一次性把一千万条数据加载到 mysql 服务器的内存里吗?这样 mysql 服务器会有 oom 的风险吧?
还请各位大大们解答。
有几点可以明确:
1:
select语句不一定会让mysql加载数据到内存(前提是命中索引),而是在发送数据的时候一条一条的读取数据。2:
查询如果是有条件的,发送时候怎么知道读取哪些数据呢?可以理解为,mysql查询期间保存了要返回的数据地址列表,发送期间,读取地址对应的数据,然后发送。(1000万的数据地址,确实也不大)3:
客户端可以选择一次性读取,也可以一条一条读(Rows方式),一条一条读取也不会oom。但是如果客户端处理慢的话(比如处理1000万条需要1天时间),会让mysql端发送数据处理阻塞状态(sending data) 这篇文章可以参考:smartkeyerror.com/MySQL-Sending-Da...