mysql 鸟瞰整体,给我一条语句我是这样执行

mysql专栏为你弥补这块的短板

后续我会在这块给大家带来mysql方面的知识,分享我在这块的经验。
mysql学习是一个漫长的过程,我希望大家能够不要浮躁,静下心来好好的学习基础知识,先把心法学会了,招式就是千变万化。平时我们使用数据库,看到的通常是一个整体。比如,你有一个最简单的表,表里有一个字段X、下面有一个执行语句:

mysql>select * from mytable where X=?;
或者更加复杂的语句。。。我这里就不在举例了。

我们看到给出一个语句,如果数据库有数据就会返回相应的结果。却不知道这条语句在MYSQL内部是如何执行的,我今天就给大家拆解一下MYSQL,希望这个拆解过程能让你对MYSQL有更深入的理解,这样我们遇到一些问题,或者异常我们能够快速的定位并且解决问题。
先看一下MYSQL官方的架构:
在这里插入图片描述

连接器
第一步,你会先连接到数据库,这个时候就是mysql连接器负责跟客户端建立连接,获取权限,管理连接。
linux命令连接mysql如下:

mysql -h&ip -P&port -u&username -p&password
不建议直接输入密码,存在安全隐患,最好直接-p enter 输入你的密码

在完成和服务器端TCP的三次握手后,就会验证身份,如果用户名和密码不对就会提示ERROR 1045 (28000): Access denied for user ‘meiling’@‘yourip’ (using password: YES)

如果登录成功后,我们在通过root权限对其修改权限,是不影响已经登录后权限的限制。我就不列出来了,大家可以自己尝试一下。

连接完成后,我们不操作任何命令,连接就处于空闲状态,我们用show processlist看看情况。
在这里插入图片描述
可以看到状态是 "sleep"就是空闲状态客户端很久都没操作,连接器就会自动断开。这个时间的参数可以看 wait_timeout,默认是8小时。

mysql> show variables like '%wait_timeout%';
+--------------------------+----------+
| Variable_name            | Value    |
+--------------------------+----------+
| innodb_lock_wait_timeout | 50       |
| lock_wait_timeout        | 31536000 |
| wait_timeout             | 28800    |
+--------------------------+----------+
3 rows in set
mysql> 

我们可以看到是28800秒,换算成小时就是8个小时。你们可以自己看一下这个参数。

数据库经典8小时问题,就是这个默认参数如果发现一个连接的空闲时间超过8小时,将会在数据库端自动关闭这个连接。而数据源并不知道这个连接已经关闭了,当它将这个无用的连接返回给某个dao时,dao就会报无法获取connection异常。
所以我们可以针对这个参数来防止线上问题的发生哦,这个比较隐患。
1.我们可以适当的调整timeout的大小。
2.通过应用层当有空闲的连接的时候,就去激活一下,免得过期造成连接丢失。

数据的连接我们尽量的减少连接次数,连接的过程非常的复杂,太耗费资源,基本上都是长连接。 案例:有一次我们线上的数据库宕机了,发现非常多的连接导致内存涨的非常的快,长期累积的长连接导致我们内存占用过大,被系统强制杀掉了mysql进程。 原因分析:就是因为mysql在执行过程中使用的内存是在连接对象管理的,这些资源只会在连接断开后才会释放。 1,我们就在应用程序里面定期断开长连接,具体的实现我会专门有一篇文章(如何断开连接) 2,通过mysql_reset_connection方式来重置连接。下面是mysql官方提供的api说明

27.8.7.60 mysql_reset_connection()
int mysql_reset_connection(MYSQL *mysql)

说明
重置连接以清除会话状态。

mysql_reset_connection() 具有类似于 mysql_change_user() 的效果或自动重新连接,但连接未关闭并重新打开,并且未执行重新认证。见 Section 27.8.7.3, “mysql_change_user()” )并参见 Section 27.8.20, “C API Automatic Reconnection Control” )。

与连接相关的状态受影响如下:

回滚任何活动事务并重置自动提交模式。

释放所有表锁。

所有 TEMPORARY 表都已关闭(并已删除)。

会话系统变量重新初始化为相应的全局系统变量的值,包括由 SET NAMES 等语句隐式设置的系统变量。

用户变量设置丢失。

准备好的声明已经发布。

HANDLER 变量已关闭。

LAST_INSERT_ID() 的值重置为0。

使用 GET_LOCK() 获取的锁定被释放。

返回值
成功归零。如果发生错误,则为非零。

查询缓存

这个很简单,就是一个key-value的方式。
假如一条sql语句 select * from T where id=1;就会通过key是sql语句去map中查询是否有这条语句,如果有就直接返回,没有就执行后面的流程,把数据通过key-value的方式存储。
查看mysql是否开启缓存,执行如下命令:

mysql> show variables like '%query_cache_type%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| query_cache_type | ON   |
+------------------+-------+
1 row in set (0.00 sec)

这个可以看到mysql是否开启了缓存。
但是实际使用的我个人觉得没什么必要打开缓存,缓存命中非常的低,我们的业务经常在更改变化,如何一旦有表数据发生变化,缓存就会清除。所以实战中我们是不会打开缓存的。

命令解析层
如果缓存没有命中的话,就会分析当前的sql,分析当前的语句是查询,还是ddl,还是其他的命令。

mysql>select * from mytable where X=?; //继续解说这条

我们输入的select 这个关键词就会识别出来是查询模块,在分别把mytable识别成表名 mytable ,把字符串识X别成列X。

后面就会做语法的分析,如果语法不对就会提示你错误。

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘ad’ at line 1

我们只需要关注的是 "user near"的内容,基本上就可以知道是什么错误了。

优化器
经过分析器后,mysql就知道你要做什么了,在调用执行器钱,还要做一些优化的处理。
优化器就是选择哪种方案去执行我们的sql。
简单的使用 OPTIMIZER_TRACE
查看是否开启优化器

mysql> show variables like '%optimizer_trace%';
+------------------------------+----------------------------------------------------------------------------+
| Variable_name                | Value                                                                      |
+------------------------------+----------------------------------------------------------------------------+
| optimizer_trace              | enabled=off,one_line=off                                                   |
| optimizer_trace_features     | greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on |
| optimizer_trace_limit        | 1                                                                          |
| optimizer_trace_max_mem_size | 16384                                                                      |
| optimizer_trace_offset       | -1                                                                         |
+------------------------------+----------------------------------------------------------------------------+

  
  

开启优化器

mysql> set session optimizer_trace='enabled=on';
Query OK, 0 rows affected
mysql> show variables like '%optimizer_trace%';
+------------------------------+----------------------------------------------------------------------------+
| Variable_name                | Value                                                                      |
+------------------------------+----------------------------------------------------------------------------+
| optimizer_trace              | enabled=on,one_line=off                                                    |
| optimizer_trace_features     | greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on |
| optimizer_trace_limit        | 1                                                                          |
| optimizer_trace_max_mem_size | 16384                                                                      |
| optimizer_trace_offset       | -1                                                                         |
+------------------------------+----------------------------------------------------------------------------+
5 rows in set
//执行一条查询语句
mysql> select * from oc_user where cid='e7cf68e15ba3480f';
+-----+------------------+----------+-----------+----------+-------------+---------+-------+-----------+------------+------------+--------+---------------------+------------+
| id  | cid              | nickname | username  | password | phone       | iconURL | email | ipaddress | devicetype | macaddress | frozen | createtime          | updatetime |
+-----+------------------+----------+-----------+----------+-------------+---------+-------+-----------+------------+------------+--------+---------------------+------------+
| 129 | e7cf68e15ba3480f | NULL     | ac_3Fhtni | NULL     | 13966789831 | NULL    | NULL  | NULL      | NULL       | NULL       | NULL   | 2017-11-27 14:18:56 | NULL       |
+-----+------------------+----------+-----------+----------+-------------+---------+-------+-----------+------------+------------+--------+---------------------+------------+
1 row in set

查看优化器如何执行的


mysql> select trace from information_schema.optimizer_trace;
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| trace                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| {
  "steps": [
    {
      "join_preparation": {  //优化准备阶段
        "select#": 1,
        "steps": [
          {
          //表示出来查询的sql语句
            "expanded_query": "/* select#1 */ select `oc_user`.`id` AS `id`,`oc_user`.`cid` AS `cid`,`oc_user`.`nickname` AS `nickname`,`oc_user`.`username` AS `username`,`oc_user`.`password` AS `password`,`oc_user`.`phone` AS `phone`,`oc_user`.`iconURL` AS `iconURL`,`oc_user`.`email` AS `email`,`oc_user`.`ipaddress` AS `ipaddress`,`oc_user`.`devicetype` AS `devicetype`,`oc_user`.`macaddress` AS `macaddress`,`oc_user`.`frozen` AS `frozen`,`oc_user`.`createtime` AS `createtime`,`oc_user`.`updatetime` AS `updatetime` from `oc_user` where (`oc_user`.`cid` = 'e7cf68e15ba3480f')"
          }
        ]
      }
    },
    {
      "join_optimization": {//优化工作的主要阶段,包括逻辑和物理的2个阶段优化
        "select#": 1,
        "steps": [
          {
            "condition_processing": {//逻辑优化部分
              "condition": "WHERE", //先看where条件,
              "original_condition": "(`oc_user`.`cid` = 'e7cf68e15ba3480f')",
              "steps": [
                {
                  "transformation": "equality_propagation",//逻辑优化,条件优化,等式处理
                  "resulting_condition": "(`oc_user`.`cid` = 'e7cf68e15ba3480f')"
                },
                {
                  "transformation": "constant_propagation",//逻辑优化,条件优化,常量处理
                  "resulting_condition": "(`oc_user`.`cid` = 'e7cf68e15ba3480f')"
                },
                {
                  "transformation": "trivial_condition_removal",,//逻辑优化,条件简化,条件去除
                  "resulting_condition": "(`oc_user`.`cid` = 'e7cf68e15ba3480f')"
                }
              ]
            }
          },
          {
          //这里是逻辑优化后 where条件优化结束
            "substitute_generated_columns": {
            }
          },
          {
            "table_dependencies": [//逻辑优化,找出表之间的相互依赖关系,非直接可用的优化方式
              {
                "table": "`oc_user`",//有哪些表
                "row_may_be_null": false,//是否可以不存在行数据
                "map_bit": 0,//从0开始
                "depends_on_map_bits": [
                ]
              }
            ]
          },
          {
            "ref_optimizer_key_uses": [//逻辑优化,找出备选的索引
              {
                "table": "`oc_user`",
                "field": "cid", //这个是索引字段,下面的一样
                "equals": "'e7cf68e15ba3480f'",
                "null_rejecting": false
              }
            ]
          },
          {
            "rows_estimation": [//逻辑优化, 估算每个表的元组个数. 单表上进行全表扫描和索引扫描的代价估算. 每个索引都估算索引扫描代价(估算行数)
              {
                "table": "`oc_user`", //表名
                "rows": 1,//有多少行
                "cost": 1,//代价,这个值越大,花费的代价越大
                "table_type": "const", //表的类型
                "empty": false//是否为空
              }
            ]
          },
          {
            "condition_on_constant_tables": "('e7cf68e15ba3480f' = 'e7cf68e15ba3480f')",
            "condition_value": true
          },
          {
            "attaching_conditions_to_tables": {//逻辑优化,尽量吧条件绑定到对应的表上。
              "original_condition": "('e7cf68e15ba3480f' = 'e7cf68e15ba3480f')",
              "attached_conditions_computation": [
              ],
              "attached_conditions_summary": [
              ]
            }
          },
          {
            "refine_plan": [
            ]
          }
        ]
      }
    },
    {
      "join_execution": {
        "select#": 1,
        "steps": [
        ]
      }
    }
  ]
} |
+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set

执行器
mysql通过分析器知道了要做什么,优化器该怎么做,接下来就进入了执行器阶段,开始执行语句。 在执行语句的时候,mysql还是要坚持一下执行是否有权限,如果没有就会返回权限错误。

比如我们例子中的mytable表,字段X没有索引,那么执行器就是循环的调用InnoDb引擎接口获取表的数据,然后在对比一下是否和我们传入的值一样,如果不是就继续,是就直接存在结果集。直到取到表的最后一行数据,在把结果集返回给客户端。
到此,语句执行完毕.

发布了39 篇原创文章 · 获赞 40 · 访问量 4975

猜你喜欢

转载自blog.csdn.net/a1224645904/article/details/101347922