image.png

    全表扫描的情况下,数据并不是一下子发送给客户端的,而是边查边发:

    服务端并不需要保存一个完整的结果集。取数据和发数据的流程是这样的:
    1. 获取一行,写到 net_buffer 中。这块内存的大小是由参数 net_buffer_length 定义的,默认是 16k
    2. 重复获取行,直到 net_buffer 写满,调用网络接口发出去。
    3. 如果发送成功,就清空 net_buffer,然后继续取下一行,并写入 net_buffer。
    4. 如果发送函数返回 EAGAIN 或 WSAEWOULDBLOCK,就表示本地网络栈(socket send buffer)写满了,进入等待。直到网络栈重新可写,再继续发送。

    MySQL 是“边读边发的”,这个概念很重要。

    这就意味着,如果客户端接收得慢,会导致 MySQL 服务端由于结果发不出去,这个事务的执行时间变长。