随着曾经的一期MYSQL来自“旧金山的信息”中,MYSQL 8 大举更改数据库的优化器的事情已经是在目前版本上大举实现的事情了。而上期说的一些ORACLE 认为曾经在MYSQL上不应该实现的“好”功能,也都被取消了。同时祭出了新的MYSQL的查询分析, Explain analyze ,我们来看看 MYSQL 8 在这方面更改了多少。
首先我们看一个列子,在MYSQL5.7 上可以运行的一个查询
select distinct(es.emp_no),ss.salary,concat(es.last_name,' ',es.first_name)
from employees as es
left join salaries as ss on es.emp_no = ss.emp_no where ss.salary > 91530
group by emp_no
having max(ss.salary) ;
可以看到,这是可以查询出结果的。(但实际上这不符合 SQL 92的标准)
所以我们看看来自旧金山的 ORACLE OPEN 大会中提到的,那些不应该发生的“事情”,已经不能在MYSQL8.X上发生了,(默认SQL MODE 配置)
所以这也是上期提到了,MYSQL 的 DEVELOPER 需要接受的一些改变。
在传统的 EXPLAIN 中给出的执行计划有以下问题
1 给出的执行计划比较简单,对于复杂的查询分析出的计划阅读困难,关联性无法体现
2 给出的执行计划并非十分准确,而是评估的计划,如果要看实际的执行计划,必须进行真实的运算后,才能得到真实的执行计划
select concat(es.first_name,' ',es.last_name),ts.title
from employees as es
left join titles as ts on es.emp_no = ts.emp_no
where ts.title = 'manager' and to_date = '9999-01-01';
我们以上面的语句作为例子
| -> Nested loop inner join (cost=46084.11 rows=4422) (actual time=108.896..309.845 rows=9 loops=1)
-> Filter: ((ts.to_date = DATE'9999-01-01') and (ts.title = 'manager') and (ts.emp_no is not null)) (cost=44536.30 rows=4422) (actual time=108.366..309.135 rows=9 loops=1)
-> Table scan on ts (cost=44536.30 rows=442233) (actual time=0.516..204.424 rows=443308 loops=1)
-> Single-row index lookup on es using PRIMARY (emp_no=ts.emp_no) (cost=0.25 rows=1) (actual time=0.070..0.071 rows=1 loops=9)
从上面给出的计划来看,1 先对 TS 进行 TABLE SCAN 行数 442233 行,实际上是 443308 行, 通过 INDEX LOOKUP 的方式,每次扫描使用0.07毫秒,并且同时会过滤 to_date, title emp_no 等条件 采用 Nested loop inner join 的方式。
实际上透露了大约执行的时间和执行的次序,每行的操作的COST 等等时间,这点和ORACLE 是越来越像。并且还告诉你,实际的执行计划走的 INNER JOIN
我们在看一个列子
完全是ORALCE的风格。
当然也可以写成另外一种格式,输出是一样的
explain format=tree select concat(es.first_name,' ',es.last_name),ts.title from employees as es left join titles as ts on es.emp_no = ts.emp_no where ts.title = 'manager' and to_date = '9999-01-01';
另外可能有细心的同学会看到,actual time= xxx .. xxxxx 这里的意思是单行成本时间 和 总体成本时间,所以EXPLAIN ANALYZE 的输出已经完全和ORACLE 接轨,或者说和所有的数据库接轨( 因为 ORACLE , PG , SQL SERVER )都可以这样显示执行计划,SQL SERVER 甚至可以动态图的方式给你显示。
那么从MYSQL 8 开始一套整体的查看执行计划,或评估计划的方式已经是成为体系
1 评估执行计划可以使用 explain format=tree
2 实际的执行计划直接 explain analyze
3 明白执行计划选择的方式与路径 optimizer trace
所以MYSQL 8 的确是一份认真的作业。