MySQL数据库连接慢原因【深层次分析】
1 747 0 2020-07-20 14:23:20
有时候在连接数据库的时候,发现连接的很慢,在这里做一次进行深层次的分析,这也是一个学习的日志。
每个客户端在和服务端建立连接的时候,需要做的事情就是:
TCP 握手;
用户校验;
获取权限。
但这几个操作,显然跟库里面表的个数无关。
但实际上,当使用默认参数连接的时候,MySQL 客户端会提供一个本地库名和表名补全的功能。
为了实现这个功能,客户端在连接成功后,需要多做一些操作:
执行 show databases;
执行 show tables;
把这两个命令的结果用于构建一个本地的哈希表。
在这些操作中,最花时间的就是第三步在本地构建哈希表的操作。
所以,当一个库中的表个数非常多的时候,这一步就会花比较长的时间。
也就是说,我们感知到的连接过程慢,其实并不是连接慢,也不是服务端慢,而是客户端慢。
当然也可以设置参数,比如在连接命令中加上 -A,就可以关掉这个自动补全的功能,然后客户端就可以快速返回了。
这里自动补全的效果就是,你在输入库名或者表名的时候,输入前缀,可以使用 Tab 键自动补全表名或者显示提示。
实际使用中,如果你自动补全功能用得并不多,我建议你每次使用的时候都默认加 -A。
其实提示里面没有说,除了加 -A 以外,加–quick(或者简写为 -q) 参数,也可以跳过这个阶段。
但是,这个–quick 是一个更容易引起误会的参数,也是关于客户端常见的一个误解。你看到这个参数,是不是觉得这应该是一个让服务端加速的参数?但实际上恰恰相反,设置了这个参数可能会降低服务端的性能。
为什么这么说呢?MySQL 客户端发送请求后,接收服务端返回结果的方式有两种:一种是本地缓存,也就是在本地开一片内存,先把结果存起来。
如果你用 API 开发,对应的就是 mysql_store_result 方法。
另一种是不缓存,读一个处理一个。如果你用 API 开发,对应的就是 mysql_use_result 方法。
MySQL 客户端默认采用第一种方式,而如果加上–quick 参数,就会使用第二种不缓存的方式。
采用不缓存的方式时,如果本地处理得慢,就会导致服务端发送结果被阻塞,因此会让服务端变慢。
关于服务端的具体行为,我会在下一篇文章再和你展开说明。那你会说,既然这样,为什么要给这个参数取名叫作 quick 呢?
这是因为使用这个参数可以达到以下三点效果:
第一点,就是前面提到的,跳过表名自动补全功能。
第二点,mysql_store_result 需要申请本地内存来缓存查询结果,如果查询结果太大,会耗费较多的本地内存,可能会影响客户端本地机器的性能;
第三点,是不会把执行命令记录到本地的命令历史文件。所以你看到了,–quick 参数的意思,是让客户端变得更快。
本文链接地址,转载请标注:
https://caohongyuan.com/article/169