mysql缓慢怎么办 mysql很卡( 四 )


...
可以看到执行时间变成了 0.67s 。
整理
我们诊断的关键点如下:
\1. 对于 information_schema 中的元数据表 , 执行计划不能提供有效信息 。
\2. 通过查看 MySQL 改写后的 SQL,我们猜测了优化器发生了误判 。
\3. 我们增加了 hint,指导 MySQL 正确进行优化判断 。
但目前我们的实验仅限于猜测,猜中了万事大吉,猜不中就无法做出好的诊断 。
Mysql 查询速度慢怎么办问题
我们有一个 SQL,用于找到没有主键 / 唯一键的表 , 但是在 MySQL 5.7 上运行特别慢,怎么办?
实验
我们搭建一个 MySQL 5.7 的环境,此处省略搭建步骤 。
写个简单的脚本 , 制造一批带主键和不带主键的表:
执行一下脚本:
现在执行以下 SQL 看看效果:
...
执行了 16.80s,感觉是非常慢了 。
【mysql缓慢怎么办 mysql很卡】现在用一下 DBA 三板斧 , 看看执行计划:
感觉有点惨,由于 information_schema.columns 是元数据表,没有必要的统计信息 。
那我们来 show warnings 看看 MySQL 改写后的 SQL:
我们格式化一下 SQL:
可以看到 MySQL 将
select from A where A.x not in (select x from B) //非关联子查询
转换成了
select from A where not exists (select 1 from B where B.x = a.x) //关联子查询
如果我们自己是 MySQL,在执行非关联子查询时,可以使用很简单的策略:
select from A where A.x not in (select x from B where ...) //非关联子查询:1. 扫描 B 表中的所有记录,找到满足条件的记录,存放在临时表 C 中 , 建好索引2. 扫描 A 表中的记录 , 与临时表 C 中的记录进行比对 , 直接在索引里比对,
而关联子查询就需要循环迭代:
select from A where not exists (select 1 from B where B.x = a.x and ...) //关联子查询扫描 A 表的每一条记录 rA:扫描 B 表,找到其中的第一条满足 rA 条件的记录 。
显然,关联子查询的扫描成本会高于非关联子查询 。
我们希望 MySQL 能先"缓存"子查询的结果(缓存这一步叫物化 , MATERIALIZATION),但MySQL 认为不缓存更快 , 我们就需要给予 MySQL 一定指导 。
...
可以看到执行时间变成了 0.67s 。
整理
我们诊断的关键点如下:
\1. 对于 information_schema 中的元数据表,执行计划不能提供有效信息 。
\2. 通过查看 MySQL 改写后的 SQL,我们猜测了优化器发生了误判 。
\3. 我们增加了 hint,指导 MySQL 正确进行优化判断 。
但目前我们的实验仅限于猜测,猜中了万事大吉,猜不中就无法做出好的诊断 。
MySQL数据库服务器逐渐变慢 该怎么分析与解决我们先来看第一个阶段,MySQL慢的诊断思路,一般我们会从三个方向来做:
第一个方向是MySQL内部的观测
第二个方向是外部资源的观测
第三个方向是外部需求的改造
1.1 MySQL 内部观测
我们来看MySQL内部的观测,常用的观测手段是这样的,从上往下看,第一部分是Processlist,看一下哪个SQL压力不太正常,第二步是explain,解释一下它的执行计划,第三步我们要做Profilling,如果这个SQL能再执行一次的话, 就做一个Profilling,然后高级的DBA会直接动用performance_schema  , MySQL 5.7 以后直接动用sys_schema,sys_schema是一个视图 , 里面有便捷的各类信息,帮助大家来诊断性能 。再高级一点,我们会动用innodb_metrics进行一个对引擎的诊断 。
除了这些手段以外,大家还提出了一些乱七八糟的手段 , 我就不列在这了 , 这些是常规的一个MySQL的内部的状态观测的思路 。除了这些以外,MySQL还陆陆续续提供了一些暴露自己状态的方案,但是这些方案并没有在实践中形成套路,原因是学习成本比较高 。

推荐阅读