1、Mysql Query Optimizer
这个名称在前言部分我在Mysql的整体架构中介绍过,称为查询优化器;这个查询优化器在绝大多数的公司,是不会做任何修改和扩展的,因为业务不需要,大牛请不起等因素,也就除了阿里这些大厂变态到把这玩意改了自己用。
Mysql中有专门负责优化Select语句的优化器模块,主要功能是:通过计算分析系统中手记到的统计信息,为客户端请求的Query提供Mysql认为最优化的执行计划,认为最优的检索方式,但是不一定是DBA认为是最优的,所以这部分是调整起来最耗时间的。
当客户端向Mysql请求一条查询的时候,命令解析器会完成请求的分类,区别出是Select操作,并转发给Mysql Query Optimizer时,Optimizer首先会对整个Query进行优化,处理掉一些常量表达式的运算,直接换算成常量值,或者根据查询条件出现的顺序进行个位置交换,如去掉一些无用或者显而易见的条件,结构调整等。然后分析Query的Hint信息(如果存在的话),看显示Hint信息是不是可以完全确定Query的执行计划,如果没有Hint,或者Hint不足以完全确定执行计划,则会读取所涉及对象的统计信息,根据Query进行写相应的计算分析,最后得出执行计划,这个过程,需要了解的重点是,Optimizer解析的结果和我们预期的结果不一定一样!
那Mysql是如何把自己认为最优的结果反馈给程序员或者DBA的呢,进而让Mysql更好的优化?
2、Mysql常见的性能瓶颈
CPU方面:CPU在很繁忙的时候,一般是在数据装入内存或者从磁盘上读取数据的时候,Mysql得到的CPU处理的时间片,分配的线程就远远不够。
IO:磁盘的IO也发生在装入的数据远大于内存导致磁盘IO高,Sql就会很慢,哪怕是一个最简单的查询语句。
服务器性能瓶颈,可以通过top,free,iostat,vmstat看下服务器的当前状态,是否需要升级配置。
3、Explain执行计划
概念:使用 EXPLAIN 关键字可以模拟优化器执行 SQL 查询语句,从而知道 MySQL 是如何处理你的SQL 语句的,进而分析你的查询语句或是表结构的性能瓶颈。
Explain能干这些事情:
- 表的读取顺序
- 数据读取的操作类型
- 哪些索引可以使用
- 哪些索引实际被使用
- 表之间的引用
- 每张表有多少行被优化器查询
用法: Explain+SQL 语句
假设我有个部门表:tbl_emp
执行下这个sql可以看出来:
这些字段包含的什么意思呢,通过这些字段怎么能知道我当前的sql执行是什么样的,需不需要优化?怎么玩?
3.1、id
概念:select查询的序列号,包含一组数字,表示查询中执行的select子句或者操作表的顺序,重点:子句+操作顺序
场景:
id相同,执行顺序由上至下
比如这个sql:explain select t2.* from t1, t2, t3 where t1.id = t2.id and t1.id = t3.id and t1.other_column = '';
这个Sql你认为的from 顺序是t1,t2,t3,但是不然,Mysql自己认为的是t1,t3,t2这样的顺序,所以当id相同时,执行顺序由上至下!
id不同的时候,如果是子查询,id的序号递增,id值越大优先级越高,越先被执行
比如这个sql:看下select_type列,有个subquery是子查询的意思,id=2和3的子查询,序号递增,优先级越高越先被执行,所以执行顺序是t3, t1, t2;并且仔细看这个sql,子查询正常会优先被执行,里面的结果出来,才会执行外面的。