一.全表扫描server层如何执行
使用场景:
我们现在要对一个200G的InnoDB表执行全表扫描:
mysql -h$host -P$port -u$user -p$pwd -e "select * from db">$target_file
取数据和发数据的流程:
- 获取一行,写到net_buffer中,这块内存的大小是由参数net_buffer_length定义,默认16k
- 重复,知道16k写满,网络接口发送出去,并清空缓存
- 直到函数返回EAGAIN 或 WSAEWOULDBLOCK,表示本地网络栈(socket send buffer)写满了,表示本地网络栈写满了,进入等待。直到网络栈重新可写,继续发送。

- MySQL 是“边读边发的”---流式
- 客户端接收 慢,导致MySQL服务端结果发布出去 ,事务执行时间变长
二.全表扫描对InnoDB
Buffer Pool两个作用:
- 加速更新
- 加速查询 (查询不需要读磁盘,直接从内存中取结果)
内存命中率
查看方式:
show engine innodb status结果,查看系统当前的BP命中率
InnoDB Buffer Pool的大小由参数innodb_buffer_pool_size,一般建议设置成可用物理内存60%-80%
Buffer Pool如何淘汰数据
三.Least Rencently Used--LRU算法
淘汰最久未使用数据
存在问题:
- 全表扫描的时候,Buffer Pool 里的数据全部淘汰掉,存入扫描过程中访问到的数据页的内容
- 此时,业务数据进来会导致内存命中率急剧下降,磁盘压力增加,SQL 语句响应变慢
解决方案:
改进版LRU算法---为全表扫描的操作量身定制
利用特点:该数据页只会全表扫描的时候被 访问间隔不会超过 1 秒 -----控制LRU认定最近条件即可