你了解mysql是如何执行查询语句的嘛?

关注微信公众号程序媛小水,与您一块儿进步mysql

应该有不少朋友都用过或者据说过数据库mysql,那么你清楚mysql对查询是怎么运做的嘛? 这篇文章水水就来分享一下mysql是如何执行查询语句。sql

安装mysql

首先咱们须要安装mysql服务器,我是在ubuntu 16.04环境下进行安装。数据库

1. 打开终端,更新软件包列表

$ sudo apt update
复制代码

2. 安装mysql

$ sudo apt-get install mysql-server mysql-client
复制代码

3. mysql脚本进行初始化

$ sudo mysql_secure_installation
复制代码

执行这条命令时会出现几回mysql的询问:修改root帐号的密码、移除匿名用户、容许远程登陆、删除test数据库。ubuntu

4. 登陆

mysql -u root -p
复制代码

5. 建立MySQL数据库和用户

$ create database datatest;   # 建立一个名为datatest的数据库
mysql> create user`moly`@`*`  identified by'123456';   #建立molly用户
复制代码

ps:在建立用户时 须要注意(我就是踩坑里了弄了半天)缓存

user`moly`@`*` 须要用 反引号 ` 
复制代码

可是水水仍是遇到了问题bash

这个时候只要执行这个就能够啦~

# flush privileges 命令的做用是mysql用户数据和权限有修改后,不重启MySQL服务直接生效。
mysql> flush privileges
复制代码

以后就能够开心的添加用户啦~服务器

能够查看一下咱们建立好的数据库~微信

mysql> show databases;
复制代码

查看链接的数据库架构

mysql> show processlist; 
复制代码

若是不须要能够进行删除~ide

mysql> drop databases datatest;
复制代码

作完了这些准备工做,就要到今天的重点-mysql究竟是怎么实现语句查询的呢?

mysql 的基本架构

MySQL 能够分为 Server 层存储引擎层两部分。

这里我画了一个图,不太好看你们先凑合看哈~

Server 层

包括链接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及全部的内置函数(如日期、时间、数学和加密函数等),全部跨存储引擎的功能都在这一层实现,好比存储过程、触发器、视图等。 而存储引擎层负责数据的存储和提取

链接器

mysql服务器与客户端进行链接。

本地链接 mysql -u 用户名 -p 密码

远程链接 mysql -h 远程ip或域名 -p 端口 -u 用户名 -p 密码

mysql -u root -p
复制代码

虽然密码也能够直接跟在 -p 后面写在命令行中,但可能会致使你的密码泄露。

链接器作了几个工做?

  1. 将客户端链接到服务端

  2. 获取到权限等信息

    从权限表里边查询用户权限并保存在一个变量里边以供查询缓存。

    分析器,执行器在检查权限的时候使用。

  3. 在链接的有效时长内对sql进行处理。

interactive_timeout
wait_timeout
复制代码

其中 wait_timeout是非交互式链接的空闲超时,interactive_timeout是交互式链接的空闲超时。

长连接的危害

在链接时最好使用长连接,可是MySQL 在执行过程当中临时使用的内存在链接的对象里,而且这些资源会在链接断开的时候才释放。 因此会占用不少内存,达到必定值后有可能被系统强制杀死。

怎么解决?

有两个方法:

  1. 按期断开长链接。

    使用一段时间,或者执行过一个占用内存的查询操做后,断开链接。

  2. 可使用这个API来从新初始化链接资源,将链接恢复到刚刚建立完时的状态。

    mysql_reset_connection
    复制代码

查询缓存

拿到语句,先到缓存以(key-value的形式查询),若是内存中有,则把value返回。你们可能以为缓存这个东西不错嗷,能够减小mysql的工做量。若是以前查询过直接把值拿过来就能够了。可是水水却以为缓存尽可能别用~你们先别急,往下看。

为何不用缓存?

查询缓存的失效很是频繁,只要有一个表的更新,那么这个表上全部的查询缓存都会被清空。这就会引起一个很大的问题,对于更新频繁的数据库来讲,查询缓存的命中率会很是低。并且查询缓存是要从内存中去查询,命中率低会影响数据库服务器的性能。所以水水建议若是数据库表常常更新,最好不要使用缓存。

如何查看缓存?

mysql> show variables like '%query_cache%';
复制代码

如何设置不使用缓存?

  1. 将参数 query_cache_type 设置成 DEMAND,这样对于默认的 SQL 语句都不使用查询缓存。
  2. 也能够用 SQL_NO_CACHE 指定
mysql> select SQL_NO_CACHE count(host) from user;
复制代码

分析器

分析器主要负责将命令拆分红词来进行词法和语法分析。

词法分析:识别关键字,表名,列名等等(查看表,列是否存在)从information schema里面得到表的信息的。

语法分析:是否知足sql语法

mysql是如何进行语法分析的呢?

答案是经过解析器和预处理器~

  1. mysql经过 关键词 将sql命令语句解析成一棵 “解析树”

  2. 解析器处理语法和解析查询,主要有验证关键词的拼写和顺序是否正确。

    若是语法不正确会出现 "You have an error in your SQL syntax"

  3. 预处理器进一步检查解析树是否合法。主要有 检查表和列是否存在,别名是否被占用等等。

  4. 预处理器验证用户是否有查询权限。

    若是经过则生成新的解析树,再提交给优化器。

优化器

决定使用哪一个索引(表中有多个索引) 或者在一个语句有多表关联(join)的时候,决定各个表的链接顺序。最后生成执行计划进入执行器。

执行器

  1. 判断是否有这个表的查询权限
res= select_precheck(thd, lex, all_tables, first_table);
复制代码
  1. 根据指令,经过API调用底层存储引擎执行。

    mysql实现了一个抽象接口层 handler(sql/handler.h)

有了分析器的权限的检查为何还须要执行器的权限检查??

若是使用触发器,得在执行器阶段才能肯定。 因此分析器工做结束后的precheck是不能对这种运行时涉及到的表进行权限校验的,因此须要在执行器阶段进行权限检查。 另外正是由于有precheck这个步骤,才会在报错时报的是用户无权限,而不是 k字段不存在,以避免暴露表结构。

相关文章
相关标签/搜索