关注微信公众号程序媛小水,与您一块儿进步mysql
应该有不少朋友都用过或者据说过数据库mysql,那么你清楚mysql对查询是怎么运做的嘛? 这篇文章水水就来分享一下mysql是如何执行查询语句。sql
首先咱们须要安装mysql服务器,我是在ubuntu 16.04环境下进行安装。数据库
$ sudo apt update
复制代码
$ sudo apt-get install mysql-server mysql-client
复制代码
$ sudo mysql_secure_installation
复制代码
执行这条命令时会出现几回mysql的询问:修改root帐号的密码、移除匿名用户、容许远程登陆、删除test数据库。ubuntu
mysql -u root -p
复制代码
$ 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 能够分为 Server 层和存储引擎层两部分。
这里我画了一个图,不太好看你们先凑合看哈~
包括链接器、查询缓存、分析器、优化器、执行器等,涵盖 MySQL 的大多数核心服务功能,以及全部的内置函数(如日期、时间、数学和加密函数等),全部跨存储引擎的功能都在这一层实现,好比存储过程、触发器、视图等。 而存储引擎层负责数据的存储和提取。
mysql服务器与客户端进行链接。
本地链接 mysql -u 用户名 -p 密码
远程链接 mysql -h 远程ip或域名 -p 端口 -u 用户名 -p 密码
mysql -u root -p
复制代码
虽然密码也能够直接跟在 -p 后面写在命令行中,但可能会致使你的密码泄露。
将客户端链接到服务端
获取到权限等信息
从权限表里边查询用户权限并保存在一个变量里边以供查询缓存。
分析器,执行器在检查权限的时候使用。
在链接的有效时长内对sql进行处理。
interactive_timeout
wait_timeout
复制代码
其中 wait_timeout是非交互式链接的空闲超时,interactive_timeout是交互式链接的空闲超时。
在链接时最好使用长连接,可是MySQL 在执行过程当中临时使用的内存在链接的对象里,而且这些资源会在链接断开的时候才释放。 因此会占用不少内存,达到必定值后有可能被系统强制杀死。
有两个方法:
按期断开长链接。
使用一段时间,或者执行过一个占用内存的查询操做后,断开链接。
可使用这个API来从新初始化链接资源,将链接恢复到刚刚建立完时的状态。
mysql_reset_connection
复制代码
拿到语句,先到缓存以(key-value的形式查询),若是内存中有,则把value返回。你们可能以为缓存这个东西不错嗷,能够减小mysql的工做量。若是以前查询过直接把值拿过来就能够了。可是水水却以为缓存尽可能别用~你们先别急,往下看。
查询缓存的失效很是频繁,只要有一个表的更新,那么这个表上全部的查询缓存都会被清空。这就会引起一个很大的问题,对于更新频繁的数据库来讲,查询缓存的命中率会很是低。并且查询缓存是要从内存中去查询,命中率低会影响数据库服务器的性能。所以水水建议若是数据库表常常更新,最好不要使用缓存。
mysql> show variables like '%query_cache%';
复制代码
mysql> select SQL_NO_CACHE count(host) from user;
复制代码
分析器主要负责将命令拆分红词来进行词法和语法分析。
词法分析:识别关键字,表名,列名等等(查看表,列是否存在)从information schema里面得到表的信息的。
语法分析:是否知足sql语法
答案是经过解析器和预处理器~
mysql经过 关键词 将sql命令语句解析成一棵 “解析树”
解析器处理语法和解析查询,主要有验证关键词的拼写和顺序是否正确。
若是语法不正确会出现 "You have an error in your SQL syntax"
预处理器进一步检查解析树是否合法。主要有 检查表和列是否存在,别名是否被占用等等。
预处理器验证用户是否有查询权限。
若是经过则生成新的解析树,再提交给优化器。
决定使用哪一个索引(表中有多个索引) 或者在一个语句有多表关联(join)的时候,决定各个表的链接顺序。最后生成执行计划进入执行器。
res= select_precheck(thd, lex, all_tables, first_table);
复制代码
根据指令,经过API调用底层存储引擎执行。
mysql实现了一个抽象接口层 handler(sql/handler.h)
若是使用触发器,得在执行器阶段才能肯定。 因此分析器工做结束后的precheck是不能对这种运行时涉及到的表进行权限校验的,因此须要在执行器阶段进行权限检查。 另外正是由于有precheck这个步骤,才会在报错时报的是用户无权限,而不是 k字段不存在,以避免暴露表结构。