腾讯网qq网站,静安网站建设哪家好,宿迁经济技术开发区属于哪个区,门户网站改版建议主机内存只有100G#xff0c;现在对一个200G的大表进行扫描#xff0c;会不会把数据库的内存用完。
对大表做全表扫描对Sever层的影响
假设现对一个200G的InnoDB表db1#xff0c;做一个全表扫描#xff0c;当然要把扫描结果保存到客户端。
InnoDB的数据时保存在主键索引…主机内存只有100G现在对一个200G的大表进行扫描会不会把数据库的内存用完。
对大表做全表扫描对Sever层的影响
假设现对一个200G的InnoDB表db1做一个全表扫描当然要把扫描结果保存到客户端。
InnoDB的数据时保存在主键索引上的所以全表扫描实际上是扫描表t的主键索引最后返回给客户端。
返回的结果集并不是完整的因为MySQL是边读边发的 流程为1.获取一行写到net_buffer当中net_buffer是由net_buffer_length定义的默认为16k。 2.重复获取知道net_buffer写满调用网络接口发送出去。 3.若是发送成功就清空net_buffer然后继续读取下一行写入net_buffer 4.若发送函数返回EAGAIN或WSAEWOULDBLOCK就表示本地网络栈写满直到网络栈重写可写再继续重复操作。
一个查询在发送过程当中占用MySQL内部最大内存就是net_buffer这么大并不会达到200G。这意味着若客户端接收慢MySQL就会由于结果发送不出去导致事务执行的时间变长。
若是客户端不读socket receive buffer中的内容然后再show processlist中可以看到state处于一个Sending to client的状态。
对于线上业务来说若是一个查询的返回结果不会很多就可以在客户端使用一个-quick参数就可以使用mysql_use_result这个方法读一行处理一行。当然前提是查询返回结果不多若是看到多个线程都处于Sending to client可以将net_buffer_length设置为一个更大的值。
Sending data
MySQL查询语句在进入执行阶段之后首先将状态设置为Sending data再继续执行语句的流程执行完成后就会将状态改为空字符串。
也就是说在一个线程处于“等待客户端的状态”才会显示未Sending to clientSending data是正在执行。
全表扫描对InnoDB的影响
InnoDB内存的作用是保持更新结果在配合redo log避免了随机写盘内存的数据页是在BUffer Pool中管理的。
BUffer Pool还有一个加速功能因为有WAL机制当时事务要提交的时候有一个查询要读该内存页就可以直接读因为这个时候内存页是最新的直接读内存页就可以了无需将redo log应用到数据页当中再读取。
Buffer Pool对于查询加速效果还有一个重要的指标内存命中率一般情况下内存命中率要在99%以上。
InnoDB Buffer Pool大小是由参数innodb_buffer_pool_size决定的一般设置为物理内存的60%-80%。
innodb_buffer_pool_size小于磁盘的数据量很常见若一个buffer pool满了就要淘汰一个旧数据页来更新一个新数据页。InnoDB通过改进LRU算法来实现这一目标。
LRU算法假设内存当中有P1P2P3,P4,P5这么多数据页是以链表形式保存的P1是刚刚更新的所以在头部这个时候有请求访问P3P3就会被移动到头部现在要更新一个数据页因为内存满了要删除一个就会删除尾巴的P5数据页。
InnoDB改进InnoDB将其进行改进以5:3将空间分为young和old区域young区域中的操作和原LRU算法相同。
在old区域每次被访问的时候做如下的操作
1.若这个数据页在LRU链表中存在时间超过1秒就移动到头部。
2.若是短于1秒位置保持不变
时间有参数Innodb_old_blacks_time控制单位为毫秒默认一秒。