MySql(随记)

2023-09-17 13:56:50

一条MySql执行过程

首先Mysql的架构分为两层,Server层和存储引擎层。
Server层:MySql大多数核心功能,主要包括,连接器,查询缓存,解释器,预处理器,优化器,执行器等
存储引擎层:负责数据的获取和存储。(innodb,MyISAM)

连接器

1.首先经过TCP三次握手,随后进行权限验证,若有问题则返回“Access denied for user”。若无问题则权限验证成功,后续该用户在此连接里的任何操作,都会基于连接开始时读到的权限进行权限逻辑的判断。所以,如果一个用户已经建立了连接,即使管理员中途修改了该用户的权限,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用新的权限设置
2.show processlist:查看连接命令
3.其中Command 命令行为Sleep则代表为空闲连接,空闲连接的最大空闲时长,由 wait_timeout 参数控制的,默认值是 8 小时(28880秒)
4.MySQL 服务支持的最大连接数由 max_connections 参数控制
5.有短链接(执行一次SQL就建立并断开一次连接),长连接(在连接期间执行多条SQL)
长连接占内存的问题如何解决?
1.定期断开长连接 2.客户端主动重置连接(这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。)

查询缓存

这个查询缓存是以 key-value 形式保存在内存中的,key 为 SQL 查询语句,value 为 SQL 语句查询的结果。查询语句到来时,先查询缓存,若命中则返回,若未命中则继续查询。
为什么查询缓存用处不大?
只要一个表有更新操作,那么这个表的查询缓存就会被清空。而更新操作是比较频繁的

解析SQL

1.词法分析。MySQL 会根据你输入的字符串识别出关键字出来,如关键字SELECT,UPDATE,FROM等
2.语法分析。根据词法分析的结果,语法解析器会根据语法规则,判断你输入的这个 SQL 语句是否满足 MySQL 语法,如果没问题就会构建出 SQL 语法树,这样方便后面模块获取 SQL 类型、表名、字段名、 where 条件等等。

执行SQL

执行SQL主要有三个阶段:
prepare 阶段,也就是预处理阶段;
optimize 阶段,也就是优化阶段;
execute 阶段,也就是执行阶段;

1.预处理器

主要做两件事1.检查查询语句中的表和字段是否存在。2. 将 select * 中的 * 符号,扩展为表上的所有列;

2.优化器

优化器主要负责将 SQL 查询语句的执行方案确定下来,比如在表里面有多个索引的时候,优化器会基于查询成本的考虑,来决定选择使用哪个索引。

3.执行器

MySQL 就真正开始执行语句了,这个工作是由「执行器」完成的。在执行的过程中,执行器就会和存储引擎交互了,交互是以记录为单位的。
主要三种方式执行过程,执行器和存储引擎的交互过程如下:
主键索引查询:
执行器第一次查询,会调用 read_first_record 函数指针指向的函数,因为优化器选择的访问类型为 const,这个函数指针被指向为 InnoDB 引擎索引查询的接口,把条件 id = 1 交给存储引擎,让存储引擎定位符合条件的第一条记录。
存储引擎通过主键索引的 B+ 树结构定位到 id = 1的第一条记录,如果记录是不存在的,就会向执行器上报记录找不到的错误,然后查询结束。如果记录是存在的,就会将记录返回给执行器;
执行器从存储引擎读到记录后,接着判断记录是否符合查询条件,如果符合则发送给客户端,如果不符合则跳过该记录。
执行器查询的过程是一个 while 循环,所以还会再查一次,但是这次因为不是第一次查询了,所以会调用 read_record 函数指针指向的函数,因为优化器选择的访问类型为 const,这个函数指针被指向为一个永远返回 - 1 的函数,所以当调用该函数的时候,执行器就退出循环,也就是结束查询了。
全表扫描:
执行器第一次查询,会调用 read_first_record 函数指针指向的函数,因为优化器选择的访问类型为 all,这个函数指针被指向为 InnoDB 引擎全扫描的接口,让存储引擎读取表中的第一条记录
执行器会判断读到的这条记录的 name 是不是 iphone,如果不是则跳过;如果是则将记录发给客户的(是的没错,Server 层每从存储引擎读到一条记录就会发送给客户端,之所以客户端显示的时候是直接显示所有记录的,是因为客户端是等查询语句查询完成后,才会显示出所有的记录)。
执行器查询的过程是一个 while 循环,所以还会再查一次,会调用 read_record 函数指针指向的函数,因为优化器选择的访问类型为 all,read_record 函数指针指向的还是 InnoDB 引擎全扫描的接口,所以接着向存储引擎层要求继续读刚才那条记录的下一条记录,存储引擎把下一条记录取出后就将其返回给执行器(Server层),执行器继续判断条件,不符合查询条件即跳过该记录,否则发送到客户端;
一直重复上述过程,直到存储引擎把表中的所有记录读完,然后向执行器(Server层) 返回了读取完毕的信息;
执行器收到存储引擎报告的查询完毕的信息,退出循环,停止查询。
索引下推:
索引下推能够减少二级索引在查询时的回表操作,提高查询的效率,因为它将 Server 层部分负责的事情,交给存储引擎层去处理了。
不使用索引下推(MySQL 5.6 之前的版本)时,执行器与存储引擎的执行流程是这样的:
Server 层首先调用存储引擎的接口定位到满足查询条件的第一条二级索引记录,也就是定位到 age > 20 的第一条记录;
存储引擎根据二级索引的 B+ 树快速定位到这条记录后,获取主键值,然后进行回表操作,将完整的记录返回给 Server 层;
Server 层在判断该记录的 reward 是否等于 100000,如果成立则将其发送给客户端;否则跳过该记录;
接着,继续向存储引擎索要下一条记录,存储引擎在二级索引定位到记录后,获取主键值,然后回表操作,将完整的记录返回给 Server 层;
如此往复,直到存储引擎把表中的所有记录读完。、
没有索引下推的时候,每查询到一条二级索引记录,都要进行回表操作,然后将记录返回给 Server,接着 Server 再判断该记录的 reward 是否等于 100000。
使用索引下推后,判断记录的 reward 是否等于 100000 的工作交给了存储引擎层,过程如下 :
Server 层首先调用存储引擎的接口定位到满足查询条件的第一条二级索引记录,也就是定位到 age > 20 的第一条记录;
存储引擎定位到二级索引后,先不执行回表操作,而是先判断一下该索引中包含的列(reward列)的条件(reward 是否等于 100000)是否成立。如果条件不成立,则直接跳过该二级索引。如果成立,则执行回表操作,将完成记录返回给 Server 层。
Server 层在判断其他的查询条件(本次查询没有其他条件)是否成立,如果成立则将其发送给客户端;否则跳过该记录,然后向存储引擎索要下一条记录。
如此往复,直到存储引擎把表中的所有记录读完。
可以看到,使用了索引下推后,虽然 reward 列无法使用到联合索引,但是因为它包含在联合索引(age,reward)里,所以直接在存储引擎过滤出满足 reward = 100000 的记录后,才去执行回表操作获取整个记录。相比于没有使用索引下推,节省了很多回表操作。

更多推荐

人大女王大学金融硕士——人生的每一刻,都是在为自己的明天铺垫

随着社会经济的迅速发展,经济全球化不断扩大。许多学子想要体验到更加多元化的教育,却又不想出国,那么中外合作办学硕士便是最好的方式。作为金融人士的你,不妨看看中国人民大学与加拿大女王大学合办的金融硕士项目,或许会给你带来全新的体验。什么是中外合作办学硕士?中外合作办学硕士是依据中外合作办学条例及教育部相关规章和文件,由中

linux入门到精通-第三章-vi(vim)编辑器

目录文本编辑器gedit介绍vi(vim)命令模式命令模式编辑模式末行模式帮助教程保存文件切换到编辑模式光标移动(命令模式下)复制粘贴删除撤销恢复保存退出查找替换可视模式替换模式分屏其他用法配置文件文本编辑器gedit介绍gedit是一个GNOME桌面环境下兼容UTF-8的文本编辑器。它使用GTK+编写而成,它十分的简

HTTP 协商缓存 Last-Modified,If-Modified-Since

浏览器第一次跟服务器请求一个资源,服务器在返回这个资源的同时,在responeheader加上Last-Modified属性(表示这个资源在服务器上的最后修改时间):-----------------------------------------------------------------------------

如何使用jenkins、ant、selenium、testng搭建自动化测试框架

如果在你的理解中自动化测试就是在eclipse里面讲webdriver的包引入,然后写一些测试脚本,这就是你所说的自动化测试,其实这个还不能算是真正的自动化测试,你见过每次需要运行的时候还需要打开eclipse然后去选择运行文件吗?没有吧!应为那样真的是很low的!下面说一下经理的两种自动化测试:一、将脚本写好,放在服

【Redis】redis实现限流

【Redis】redis实现限流【一】固定窗口【二】滑动窗口【三】令牌桶【四】深入分析Zset的数据结构【一】固定窗口所谓固定窗口限流就是时间窗口的起始和节数时间是固定的,在固定时间段内允许要求的请求数量访问,超过这个数量就会拒绝;当固定时间段结束后,再重新开始下一个时间段进行计数。我们可以根据当前的时间,以分钟为时间

PHP8中的构造方法和析构方法-PHP8知识详解

今日分享的内容是php8中的构造方法和析构方法,我们把构造方法和析构方法这两个方法分开来讲:1、构造方法构造方法存在于每个声明的类中,主要作用是执行一些初始化任务。如果类中没有直接声明构造方法,那么类会默认地生成一个没有参数且内存为空的构造方法。在PHP8中,构造方法的方法名称必须是两个下划线开头的,即“__const

Java多线程编程-线程间协作wait/notify

前言:本文是基于《Java多线程编程实战指南》第五章个人理解,源码是摘抄作者的源码,源码会加上自己的理解。等待与通知:wait/notify单线程的变成中,如果程序需要在满足一定条件间下操作一个目标动作,就需要if语句,而在多线程中处理这种情况,保护条件可能只是暂时的,稍后其他线程可能更新了保护条件设计共享变量而使其成

如何通过快解析测试接口内外网?本地内网ip让外网访问连接

接口调试测试是网络技术员经常工作内容之一。如在公司内部api项目webserver测试,在公司内办公室个人电脑是正常用内网IP访问连接测试的,但在外网电脑需要远程测试时需要怎么测试呢?这里提供一种内网地址让外网访问的通用方法:快解析内网映射。内网地址在外网访问的原理主要是通过快解析软件方式,将本地内网地址转换成外网可以

adb操作及常用命令

问题:nodevices/emulatorsfound:adbdevices没有连接的设备解决方案:大概率是因为usb调试功能没有打开,可以查看手机设备是否开启usb调试功能Android若未开启,可通过设置-关于手机,连续点击版本号7次,打开开发者模式后开启usb调试常用命令汇总查看连接计算机的设备:adbdevic

基于SpringBoot+Vue的旅游管理系统

目录前言一、技术栈二、系统功能介绍登录界面管理员功能模块用户功能模块三、核心代码1、登录模块2、文件上传模块3、代码封装前言随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势,旅游网站当然也不能排除在外,随着旅游网站的不断成熟,它彻底改变了过去传统的旅游网站方式,不仅使旅游管理难度变

WebGIS开发教程:mapbox和Cesium的区别

Mapbox和Cesium都是WebGIS领域中的开源⼯具,它们都提供了丰富的地图显示和数据可视化功能,而且都能实现三维可视化开发,但是他们在某些方面确实有一定区别。1.定位不同:Mapbox更注重静态地图和动态地图的制作和展示,特别是在移动设备和Web应用程序中的实现方面,提供了强⼤的地图渲染引擎和⼯具,能够快速构建

热文推荐