大数据对数据库的影响
全表扫描对server层的影响
1.获取一行,写入net_buffer。大小由net_buffer_length决定,默认16K。
2.重复获取行,直到net_buffer写满,调用网络接口发出去。
3.如果发送出去,就清空net_buffer,继续写入net_buffer。
4.如果发送函数返回EAGAIN或WSAEWOULDBLOCK,就表示本地网络栈(socket send buffer写满了),进入等待。直到网络栈重新可写,在继续发送。
MySQL是“边读边发的”,如果客户端接受得慢,会导致MySQL服务端由于结果发不出去,这个事务的执时间边长。
因此,对于正常的线上业务来说,如果一个查询结果不会很多的话,建议使用mysql_store_result这个接口,直接把查询结果保存在本地内存。
一个查询语句的状态变化是这样的
- MySQL查询语句进入执行阶段后,首先把状态设置成“Sending data”
- 然后,发送执行结果的列相关的信息给客户端
- 再执行执语句的流程
- 执行完成后,把状态设置成空字符串。
“Sending data”并不是指“正在发送数据”,而可能是处于执行器过程中的任意阶段。
当一个线程处于“等待客户端接受结果”的状态,才会显示“Sending to client“;如果显示成”Sending data“,意思是正在执行。
全表扫描对InnoDB的影响
内存的数据页是在Buffer Pool(BP)中管理,在WAL里Buffer Pool起到了加速更新的作用。而实际上,Buffer Pool还是一个更重要的作用,加速查询。
Buffer Pool对查询的加速效果,依赖一个重要的指标,即:内存命中率。
可以通过show engine innodb status,查看BP命中率,一个稳定服务的线上系统,要保证响应时间符合要求的话,内存命中率要99%.
InnoDB buffer Pool的大小是由参数innodb_buffer_pool_size确定的,一般建议设置成可用物理内存60%-80%。
在InnoDB改进的LRU算法中,按照5:3的比例把整个LRU链表分成了young区域和old区域。
- 扫描过程中,需要新插入的数据页,都被放到了old区域;
- 一个数据页里面由多条记录,这个数据页会被多次访问到,但是由于是顺序扫描,这个数据在第一次被访问和最后一次被访问的时间间隔不会超过1秒,因此还是会被保留在old区域。
- 在继续扫描后续数据,之前的这个数据页页不会在被访问到,于是始终没有机会移到链表头部,很快就会被淘汰。
可以看见虽然也用到了Buffer Pool,但是对young区域完全没有影响,从而保证了Buffer Pool响应正常业务的查询。