quick参数是?
MySQL客户端在连接的时候可以添加一个-quick参数,MySQL客户端在发送请求后,接收服务端返回结果的方式有两种:
MySQL客户端默认采用本地缓存的方式,如果加上-quick参数,会使用第二种不缓存的方式。
quick参数的弊端?
如果采用了quick参数,如果客户端本地处理数据很慢,将会导致服务端发送结果被阻塞,因此会让服务端变慢。
MySQL服务端如何返回数据?
show global varibales like 'net_buffer_length';
socket send buffer大小默认由操作系统/proc/sys/net/core/wmem_default文件中的值指定。
MySQL客户端接收的慢,就会导致MySQL服务器由于结果发不出去,从而使该事务的执行时间变长。
如果某个Session的状态一直处于Sending to client状态,表示服务器端的网络栈写满了。(客户端使用-quick参数并且处理较慢,有可能会出现这种情况)
对于正常的线上业务,如果不是必须使用mysql_use_result这个接口,都建议使用mysql_store_result将结果缓存在客户端本地。
Sending data?
Sending data并不一定是指正在发送数据,而可能是处于执行器中的任意阶段,这是因为一个查询语句的状态变化如下:
Sending to client表示当前线程处于等待客户端接收结果的状态;Sending data只是表示正在执行。
全表扫描对InnoDB的影响
当我们在查询数据的时候,会从磁盘上读取数据页到内存中,如果内存中的数据页是最新的,可以直接读取内存也返回,不需要从磁盘上再次读取。
内存数据页是在Buffer Pool中管理的,Buffer Pool的两个重要作用是:
InnoDB Buffer Pool的大小由innodb_buffer_pool_size决定,一般建议设置成物理内存的60%~80%。
Buffer Pool对查询的加速效果依赖于内存命中率这个指标。
show engine innodb status\G;
从上图中可以看出,当前的命中率是97.7%,命中率越高,说明我们从内存页获取数据的次数越多。
由于现在磁盘和内存的数据量完全是一个量级,因此很容易出现页淘汰的现象。
InnoDB内存管理
InnoDB内存管理使用的是优化过后的最近最少使用(LRU)算法,该算法的核心就是用来淘汰最久未使用的数据。
InnoDB为什么要对LRU进行优化?
如果按照普通的LRU算法,假设我们一个很大的查询需要淘汰掉绝大多数的内存页,这将会导致Buffer Pool的内存命中率急速下降,磁盘压力增加,SQL语句会响应变慢。
InnoDB改进后的LRU算法
InnoDB的LRU算法使用链表实现,但在实现上,它按照5:3的比例把整个LRU链表分成了young区域和old区域,也就是说链表头部的5/8区域是young区域,链表尾部的3/8区域是old区域,LRU_old指向old区域的第一个位置。
改进后的LRU算法执行流程如下:
show global variables like 'innodb_old_blocks_time';