MySQL(三)一条Sql是如何执行的

2022/2/10 19:13:52

本文主要是介绍MySQL(三)一条Sql是如何执行的,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

常用操作

show databases; 显示所有数据库
use dbname; 打开数据库:
show tables; 显示数据库mysql中所有的表;
describe user; 显示表mysql数据库中user表的列信息);

连接器

mysql ‐h host[数据库地址] ‐u root[用户] ‐p root[密码] ‐P 3306

Mysql 客户端连接服务端

  1. 验证 host 、pwd
  2. 分配会话空间(加载权限等信息)(这时服务端修改权限已不起作用)

修改user密码

CREATE USER 'username'@'host' IDENTIFIED BY 'password'; //创建新用户
grant all privileges on *.* to 'username'@'%'; //赋权限,%表示所有(host)
flush privileges //刷新数据库
update user set password=password(”new-pwd′′) where user=’root’;(设置用户名密码) 
show grants for root@"%"; 查看当前用户的权限

查看客户端连接状态 show processlist;

在这里插入图片描述
可以手动杀死连接 kill <id>

客户端如果长时间不发送command到Server端,连接器就会自动将它断开。这个时间是由参数 wait_timeout 控制的,默认值 是 8 小时

查看连接多久没有操作会断开
show global VARIABLES like 'wait_timeout';
set global wait_timeout=28800; 设置全局服务器关闭非交互连接之前等待活动的秒数

在这里插入图片描述

查询缓存 (mysql8.0已经移除了查询缓存功能)

my.cnf 参数 query_cache_type 配置缓存

一般不会用,用就用按需(query_cache_type=2)

#query_cache_type有3个值
# 0 代表关闭查询缓存OFF
# 1 代表开启ON
# 2 (DEMAND)代表当sql语句中有SQL_CACHE关键词时才缓存

query_cache_type=2

select SQL_CACHE * from test where ID=5

查看当前mysql实例是否开启缓存机制

show global variables like "%query_cache_type%";

监控查询缓存的命中率

show status like'%Qcache%';

在这里插入图片描述

  • Qcache_free_blocks:表示查询缓存中目前还有多少剩余的blocks,如果该值显示较大,则说明查询缓存中的内存碎片 过多了,可能在一定的时间进行整理。
  • Qcache_free_memory:查询缓存的内存大小,通过这个参数可以很清晰的知道当前系统的查询内存是否够用,是多 了,还是不够用,DBA可以根据实际情况做出调整。
  • Qcache_hits:表示有多少次命中缓存。我们主要可以通过该值来验证我们的查询缓存的效果。数字越大,缓存效果越理想。
  • Qcache_inserts: 表示多少次未命中然后插入,意思是新来的SQL请求在缓存中未找到,不得不执行查询处理,执行 查询处理后把结果insert到查询缓存中。这样的情况的次数,次数越多,表示查询缓存应用到的比较少,效果也就不理 想。当然系统刚启动后,查询缓存是空的,这很正常。
  • Qcache_lowmem_prunes:该参数记录有多少条查询因为内存不足而被移除出查询缓存。通过这个值,用户可以适当的 调整缓存大小。
  • Qcache_not_cached: 表示因为query_cache_type的设置而没有被缓存的查询数量。
  • Qcache_queries_in_cache:当前缓存中缓存的查询数量。
  • Qcache_total_blocks:当前缓存的block数量。

使用

select SQL_CACHE * from books where ID = 2

分析器

词法分析器
根据词法分析的结果,语法分析器会根据语法规则,判断你输入的这个 SQL 语句 是否满足 MySQL 语法
如果你的语句不对,就会收到“You have an error in your SQL syntax”的错误提醒

词法分析器分成6个主要步骤完成对sql语句的分析
1、词法分析
2、语法分析
3、语义分析
4、构造执行树
5、生成执行计划
6、计划的执行

在这里插入图片描述

关于语法树深入研究可以参考这篇wiki文章: https://en.wikipedia.org/wiki/LR_parser

select id, name, age, from test where id = 1;

在这里插入图片描述

优化器

经过了分析器,MySQL 就知道你要做什么了。在开始执行之前,还要先经过优化器的处理。

优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接 顺序。

优化器阶段完成后,这个语句的执行方案就确定下来了,然后进入执行器阶段

执行器

开始执行的时候,要先判断一下你对这个表 T 有没有执行查询的权限,如果没有,就会返回没有权限的错误,如下所示 (在 工程实现上,如果命中查询缓存,会在查询缓存返回结果的时候,做权限验证。查询也会在优化器之前调用 precheck 验证权 限)

select * from test where id=10;

如果有权限,就打开表继续执行。打开表的时候,执行器就会根据表的引擎定义,去使用这个引擎提供的接口。

比如我们这个例子中的表 test 中,ID 字段没有索引,那么执行器的执行流程是这样的:

  1. 调用 InnoDB 引擎接口取这个表的第一行,判断 ID 值是不是 10,如果不是则跳过,如果是则将这行存在结果集中;
  2. 调用引擎接口取“下一行”,重复相同的判断逻辑,直到取到这个表的最后一行。
  3. 执行器将上述遍历过程中所有满足条件的行组成的记录集作为结果集返回给客户端。

bin-log归档

binlog是Server层实现的二进制日志,他会记录我们的cud操作。Binlog有以下几个特点:

  1. Binlog在MySQL的Server层实现(引擎共用)
  2. Binlog为逻辑日志,记录的是一条语句的原始逻辑
  3. Binlog不限大小,追加写入,不会覆盖以前的日志

如果,我们误删了数据库,可以使用binlog进行归档!要使用binlog归档,首先我们得记录binlog,因此需要先开启MySQL的 binlog功能。

配置my.cnf

配置开启binlog
log‐bin=/usr/local/mysql/data/binlog/mysql‐bin
注意5.7以及更高版本需要配置本项:server‐id=123454(自定义,保证唯一性);
#binlog格式,有3种statement,row,mixed
binlog‐format=ROW
#表示每1次执行写入就与硬盘同步,会影响性能,为0时表示,事务提交时mysql不做刷盘操作,由系统决定 7 sync‐binlog=1

binlog命令

show variables like '%log_bin%'; 查看bin‐log是否开启 
flush logs; 会多一个最新的bin‐log日志
show master status; 查看最后一个bin‐log日志的相关信息 
reset master; 清空所有的bin‐log日志

查看binlog内容

/usr/local/mysql/bin/mysqlbinlog ‐‐no‐defaults /usr/local/mysql/data/binlog/mysql
‐bin. 000001 查看binlog内容

binlog里的内容不具备可读性,所以需要我们自己去判断恢复的逻辑点位,怎么观察呢?
看重点信息,比如begin,commit这种 关键词信息,只要在binlog当中看到了,你就可以理解为begin-commit之间的信息是一个完整的事务逻辑,然后再根据位置 position判断恢复即可。

从bin‐log恢复数据

恢复全部数据
/usr/local/mysql/bin/mysqlbinlog ‐‐no‐defaults /usr/local/mysql/data/binlog/mysql‐bin.000001 |mysql ‐uroot ‐p tuling(数据库名)
恢复指定位置数据
/usr/local/mysql/bin/mysqlbinlog ‐‐no‐defaults ‐‐start‐position="408" ‐‐stop‐position="731"
/usr/local/mysql/data/binlog/mysql‐bin.000001 |mysql ‐uroot ‐p tuling(数据库)
恢复指定时间段数据
/usr/local/mysql/bin/mysqlbinlog ‐‐no‐defaults /usr/local/mysql/data/binlog/mysql‐bin.000001 ‐‐stop‐date= "2018‐03‐02 12:00:00" ‐‐start‐date= "2019‐03‐02 11:55:00"|mysql ‐uroot ‐p test(数据库)

定义一个存储过程,写入数据

drop procedure if exists tproc;
delimiter $$
create procedure tproc(i int)
begin
    declare s int default 1;
    declare c char(50) default repeat('a',50);
    while s<=i do
        start transaction;
        insert into test values(null,c);
		commit;
         set s=s+1;
     end while;
 end$$
 delimiter ;

删除数据 truncate test;

利用binlog归档 /usr/local/mysql/bin/mysqlbinlog ‐‐no‐defaults /usr/local/mysql/data/binlog/mysql‐ bin.000001 |mysql ‐uroot ‐p tuling(数据库名)



这篇关于MySQL(三)一条Sql是如何执行的的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程