MySQL进阶之(一)逻辑架构

1.1 逻辑架构剖析

服务器在处理客户端发来的请求时都做了什么处理才能产生最后的处理结果呢?下面是一张大致的流程图:
在这里插入图片描述
具体展开是这样的,大致可以分为连接层、服务层、引擎层、存储层四层结构:
在这里插入图片描述

1.1.1 连接层

客户端连接器,也就是 MySQL 服务器之外的客户端程序(与具体的语言相关),负责处理客户端的连接请求、验证用户身份,以及向客户端发送响应。同时,连接器还负责处理事务和锁定,并确保数据完整性。

连接池:提供了多个用于客户端与服务器交互的线程。

客户端访问 MySQL 服务器之前,做的第一件事就是建立 TCP 连接。经过三次握手连接成功后,MySQL 服务器对 TCP 传输过来的账号密码做身份认证、权限获取:

  • 如果用户名或密码不对,会收到一个 Access denied for user 错误,客户端程序结束执行;
  • 如果用户名密码认证通过,会从权限表查出账号拥有的权限与连接关联,之后的权限判断逻辑都将依赖于此时读到的权限。

TCP 连接收到请求后,必须要分配一个线程专门与这个客户端交互,所以还会有个线程池去走后面的流程。每一个连接从线程池中获取线程,省去了创建和销毁线程的开销。

1.1.2 服务层

Server 层主要负责建立连接、分析和执行 SQL。MySQL 大多数的核心功能模块都在这里实现,主要包括连接器、查询缓存、解析器、预处理器、优化器和执行器等。另外,所有的内置函数(比如日期、时间、数学和加密函数等)和所有的跨存储引擎的功能(比如存储过程、触发器、视图等)都在 Server 层实现。

01、基础服务组件

用于系统管理和控制。

02、SQL Interface:SQL 接口

接收 SQL 指令,返回查询结果。

  • 接收用户的 SQL 命令,并且返回用户需要查询的结果。比如 SELECT… FROM 就是调用了 SQL Interface。
  • MySQL 支持 DML(数据操作语言)、DDL(数据定义语言)、存储过程、视图、触发器、自定义函数等多种 SQL 语言接口。

03、Parser:解析器

如果没有命中缓存,就要开始真正地执行语句了,解析器会对 SQL 语句进行语法解析、语义解析、词法解析,生成语法树。

  • 在解析器中对 SQL 语句进行语法解析、语义解析、词法解析。将 SQL 语句分解成数据结构,并将这个结构
    传递到后续步骤中,之后 SQL 语句的传递和处理就是基于这个结构的。如果在分解构成中遇到错误,那么就说明这个 SQL 语句是不合理的。
  • 在 SQL 命令传递到解析器的时候会被解析器验证和解析,并为其创建语法树,并根据数据字典丰富查询语法树,会验证该客户端是否具有执行该查询的权限。创建好语法树之后,MySQL 还会对 SQL 查询进行语法上的优化,从而进行查询重写。

04、Optimizer:查询优化器

核心组件,对 SQL 进行优化,根据执行计划和表统计信息,确定最优的查询执行方式,决策是否使用索引等来获取最优结果。

  • SQL 语句在语法解析之后、查询之前会使用查询优化器确定 SQL 语句的执行路径,从而生成一个执行计划
  • 这个执行计划表明应该使用哪些索引进行查询(全表检索还是使用索引检索),表之间的连接顺序如何,最后会按照执行计划中的步骤调用存储引擎提供的方法来真正的执行查询,并将查询结果返回给用户。
  • 它使用“选取-投影-连接”策略进行查询。如:
    SELECT id, name FROM student WHERE gender = '女';
    
    这个 SELECT 查询先根据 WHERE 语句进行选取,而不是将表全部查询出来以后再进行 gender 过滤。 这个 SELECT 查询先根据 id 和 name 进行属性 投影,而不是将属性全部取出以后再进行过滤,将这两个查询条件 连接起来生成最终查询结果。

05、Caches & Buffers: 查询缓存组件

以 key-value 的方式缓存查询结果。

  • MySQL 内部维持着一些 Cache 和 Buffer,比如 Query Cache 用来缓存一条 SELECT 语句的执行结果,如果能在其中找到对应的查询结果,那么就不需要再进行查询解析、优化和执行的整个过程了,直接将结果返回给客户端。
  • 这个缓存机制是由一系列小缓存组成的。比如表缓存,记录缓存,key缓存,权限缓存等 。
  • 这个查询缓存可以在不同客户端之间共享
  • 从 MySQL 5.7.20 开始,不推荐使用查询缓存,并在 MySQL 8.0 中删除 。

1.1.3 引擎层

插件式存储引擎层( Storage Engines):在查询过程中可切换存储引擎,与底层的文件系统交互。

真正的负责了 MySQ L中数据的存储和提取,对物理服务器级别维护的底层数据执行操作,服务器通过 API 与存储引擎进行通信。不同的存储引擎具有的功能不同,这样我们可以根据自己的实际需要进行选取。

1.1.4 存储层

所有的数据,数据库、表的定义,表的每一行的内容和索引,都是存在 文件系统 上,以 文件的方式存在的,并完成与存储引擎的交互。当然有些存储引擎比如 InnoDB,也支持不使用文件系统直接管理裸设备,但现代文件系统的实现使得这样做没有必要了。在文件系统之下,可以使用本地磁盘,可以使用 DAS、NAS、SAN 等各种存储系统。

1.1.5 总结

SQL 的执行流程可以简化为这样:
在这里插入图片描述

简化为三层结构:

  1. 连接层:客户端和服务器端建立连接,客户端发送 SQL 至服务器端;
  2. SQL 层(服务层):对 SQL 语句进行查询处理;与数据库文件的存储方式无关;
  3. 存储引擎层:与数据库文件打交道,负责数据的存储和读取。

1.2 数据库缓冲池

1.2.1 为什么要有缓冲池(Buffer Pool)

MySQL 的数据是存储在磁盘里的,但是如果每次都从磁盘里读取数据,磁盘 I/O 需要消耗的时间很多,性能是极差的。所以,就考虑到加个缓存来存取数据,下次查询同样的数据的时候,直接从内存中读取即可。

InnoDB 存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能。这样做的好处是可以让磁盘活动最小化,从而减少与磁盘直接进行 I/O 的时间 。这种策略对提升 SQL 语句的查询性能来说至关重要,如果索引的数据在缓冲池里,那么访问的成本就会降低很多。

那么,有了缓冲池后:

  • 当读取数据时,如果数据存在于 Buffer Pool 中,客户端就会直接读取 Buffer Pool 中的数据,否则再去磁盘中读取。
  • 当修改数据时,首先是修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页,最后由后台线程将脏页写入到磁盘。
    在这里插入图片描述

01、Buffer Pool 有多大?

Buffer Pool 是在 MySQL 启动的时候,向操作系统申请的一片连续的内存空间,默认配置下 Buffer Pool 只有 128MB 。

可以通过调整 innodb_buffer_pool_size 参数来设置 Buffer Pool 的大小,一般建议设置成可用物理内存的 60%~80%。

02、Buffer Pool 缓存什么?

InnoDB 会把存储的数据划分为若干个「页」,以页作为磁盘和内存交互的基本单位,一个页的默认大小为 16KB。因此,Buffer Pool 同样需要按「页」来划分。

在 MySQL 启动的时候,InnoDB 会为 Buffer Pool 申请一片连续的内存空间,然后按照默认的 16KB 的大小划分出一个个的页, Buffer Pool 中的页就叫做缓存页。此时这些缓存页都是空闲的,之后随着程序的运行,才会有磁盘上的页被缓存到 Buffer Pool 中。

所以,MySQL 刚启动的时候,我们会观察到使用的虚拟内存空间很大,而使用到的物理内存空间却很小,这是因为只有这些虚拟内存被访问后,操作系统才会触发缺页中断,接着将虚拟地址和物理地址建立映射关系。

Buffer Pool 除了缓存「索引页」和「数据页」,还包括了 undo 页,插入缓存、自适应哈希索引、锁信息等等:
在这里插入图片描述
为了更好的管理这些在 Buffer Pool 中的缓存页,InnoDB 为每一个缓存页都创建了一个控制块,控制块信息包括「缓存页的表空间、页号、缓存页地址、链表节点」等。

控制块也是占有内存空间的,它是放在 Buffer Pool 的最前面,然后才是缓存页:
在这里插入图片描述
其中,控制块和缓存页之间灰色的部分称为碎片空间。至于这个碎片空间是怎么产生的,是因为分配足够多的控制块和缓存页后,可能会剩余一点空间,而这点空间并不够再分配一对控制块和缓存页了,所以这点空间自然也用不到了,因此就被称为碎片了。当然了,如果 Buffer Pool 大小设置的刚刚好的话,也可能不会产生碎片。

查询一条记录,就只需要缓冲一条记录吗?

不是的。当我们查询一条记录时,InnoDB 是会把整个页的数据加载到 Buffer Pool 中的,因为通过索引只能定位到磁盘中的页,而并不能定位到页中的某一条记录。将页加载到 Buffer Pool 后,再通过页里的页目录去定位到某条具体的记录。

1.2.2 如何管理 Buffer Pool?

01、如何管理空闲页?

Buffer Pool 是一片连续的内存空间,当 MySQL 运行一段时间后,这段连续的内存空间中的缓存页既有空闲的,也有被使用的。

当我们从磁盘读取数据时,如果通过遍历这一片连续的内存空间来找到空闲的缓存页的话,效率是非常低的。

所以,为了能够快速地找到空闲的缓存页,可以使用链表结构,将空闲缓存页的「控制块」作为链表的节点,这个链表称为 Free 链表(空闲链表):
在这里插入图片描述
Free 链表上除了有控制块,还有一个头节点,该头节点包含链表的头节点地址,尾节点地址,以及当前链表中节点的数量等信息。

Free 链表节点是一个一个的控制块,而每个控制块包含着对应缓存页的地址,所以相当于 Free 链表节点都对应一个空闲的缓存页。

有了 Free 链表后,每当需要从磁盘中加载一个页到 Buffer Pool 中时,就从 Free 链表中取一个空闲的缓存页,并且把该缓存页对应的控制块的信息填上,然后把该缓存页对应的控制块从 Free 链表中移除。

02、如何管理脏页?

设计 Buffer Pool 除了能提高读性能,还能提高写性能,也就是更新数据的时候,不需要每次都要写入磁盘,而是将 Buffer Pool 对应的缓存页标记为脏页,然后再由后台线程将脏页写入到磁盘。

为了能快速知道哪些缓存页是脏的,于是就设计出 Flush 链表,它跟 Free 链表类似的,链表的节点也是控制块,区别在于 Flush 链表的元素都是脏页:
在这里插入图片描述
有了 Flush 链表后,后台线程就可以遍历 Flush 链表,将脏页写入到磁盘。

03、如何提高缓存命中率?

Buffer Pool 的大小是有限的,对于一些频繁访问的数据我们希望可以一直留在 Buffer Pool 中,而一些很少访问的数据希望可以在某些时机可以淘汰掉,从而保证 Buffer Pool 不会因为满了而导致无法再缓存新的数据,同时还能保证常用数据留在 Buffer Pool 中。

要实现这个,最容易想到的就是最少最近使用 LRU(Least recently used)算法

该算法的思路是,链表头部的节点是最近使用的,而链表末尾的节点是最久没被使用的。那么,当空间不够了,就淘汰最久没被使用的节点,从而腾出空间。

简单的 LRU 算法的实现思路是这样的:

  • 当访问的页在 Buffer Pool 里,就直接把该页对应的 LRU 链表节点移动到链表的头部。
  • 当访问的页不在 Buffer Pool 里,除了要把页放入到 LRU 链表的头部,还要淘汰 LRU 链表末尾的节点。

如下图所示,假设 LRU 链表长度为 5,LRU 链表从左到右有 1,2,3,4,5 的页:

在这里插入图片描述
如果访问了 3 号的页,因为 3 号页在 Buffer Pool 里,所以把 3 号页移动到头部即可:
在这里插入图片描述
接下来,访问了 8 号页,因为 8 号页不在 Buffer Pool 里,所以需要先淘汰末尾的 5 号页,然后再将 8 号页加入到头部:
在这里插入图片描述

所以,我们可以了解到,Buffer Pool 里有三种页和链表来管理数据:
在这里插入图片描述

  • Free Page(空闲页),表示此页未被使用,位于 Free 链表;
  • Clean Page(干净页),表示此页已被使用,但是页面未发生修改,位于 LRU 链表。
  • Dirty Page(脏页),表示此页「已被使用」且「已经被修改」,其数据和磁盘上的数据已经不一致。当脏页上的数据写入磁盘后,内存数据和磁盘数据一致,那么该页就变成了干净页。脏页同时存在于 LRU 链表和 Flush 链表。

简单的 LRU 算法并没有被 MySQL 使用,因为简单的 LRU 算法无法避免预读失效和 Buffer Pool 污染两个问题。

什么是预读失效?

MySQL 的预读机制:程序是有空间局部性的,靠近当前被访问数据的数据,在未来很大概率会被访问到。所以,MySQL 在加载数据页时,会提前把它相邻的数据页一并加载进来,目的是为了减少磁盘 IO。

但是可能这些被提前加载进来的数据页,并没有被访问,相当于这个预读是白做了,这个就是预读失效。

如果使用简单的 LRU 算法,就会把预读页放到 LRU 链表头部,而当 Buffer Pool空间不够的时候,还需要把末尾的页淘汰掉。

如果这些预读页如果一直不会被访问到,就会出现一个很奇怪的问题:不会被访问的预读页占用了 LRU 链表前排的位置,而末尾淘汰的页,可能是频繁访问的页,这样就大大降低了缓存命中率。

怎么解决预读失效而导致缓存命中率降低的问题?

我们不能因为害怕预读失效,而将预读机制去掉,大部分情况下,局部性原理还是成立的。

要避免预读失效带来影响,最好就是让预读的页停留在 Buffer Pool 里的时间要尽可能的短,让真正被访问的页移动到 LRU 链表的头部,从而保证真正被读取的热数据留在 Buffer Pool 里的时间尽可能长

那到底怎么才能避免呢?

MySQL 是这样做的:它改进了 LRU 算法,将 LRU 划分了 2 个区域:old 区域 和 young 区域,young 区域在 LRU 链表的前半部分,old 区域则是在后半部分,如下图:
在这里插入图片描述
old 区域占整个 LRU 链表长度的比例可以通过 innodb_old_blocks_pct 参数来设置,默认是 37,代表整个 LRU 链表中 young 区域与 old 区域比例是 63:37。

划分这两个区域后,预读的页就只需要加入到 old 区域的头部,当页被真正访问的时候,才将页插入 young 区域的头部。如果预读的页一直没有被访问,就会从 old 区域移除,这样就不会影响 young 区域中的热点数据。

举个例子:

假设有一个长度为 10 的 LRU 链表,其中 young 区域占比 70 %,old 区域占比 30 %:
在这里插入图片描述
现在有个编号为 20 的页被预读了,这个页只会被插入到 old 区域头部,而 old 区域末尾的页(10号)会被淘汰掉:
在这里插入图片描述
如果 20 号页一直不会被访问,它也没有占用到 young 区域的位置,而且还会比 young 区域的数据更早被淘汰出去。

如果 20 号页被预读后,立刻被访问了,那么就会将它插入到 young 区域的头部,young 区域末尾的页(7号),会被挤到 old 区域,作为 old 区域的头部,这个过程并不会有页被淘汰:

在这里插入图片描述
虽然通过划分 old 区域 和 young 区域避免了预读失效带来的影响,但是还有个问题无法解决,那就是 Buffer Pool 污染的问题

什么是 Buffer Pool 污染?

当某一个 SQL 语句扫描了大量的数据时,在 Buffer Pool 空间比较有限的情况下,可能会将 Buffer Pool 里的所有页都替换出去,导致大量热数据被淘汰了,等这些热数据又被再次访问的时候,由于缓存未命中,就会产生大量的磁盘 IO,MySQL 性能就会急剧下降,这个过程被称为 Buffer Pool 污染。

注意:Buffer Pool 污染并不只是查询语句查询出了大量的数据才出现的问题,即使查询出来的结果集很小,也会造成 Buffer Pool 污染。

比如,在一个数据量非常大的表,执行了这条语句:

select * from t_user where name like "%xiaolin%";

可能这个查询出来的结果就几条记录,但是由于这条语句会发生索引失效,所以这个查询过程是全表扫描的,接着会发生如下的过程:

  1. 从磁盘读到的页加入到 LRU 链表的 old 区域头部;
  2. 当从页里读取行记录时,也就是页被访问的时候,就要将该页放到 young 区域头部;
  3. 接下来拿行记录的 name 字段和字符串 xiaolin 进行模糊匹配,如果符合条件,就加入到结果集里;
  4. 如此往复,直到扫描完表中的所有记录。

经过这一番折腾,原本 young 区域的热点数据就都会被替换掉。

举个例子,假设需要批量扫描:21,22,23,24,25 这五个页,这些页都会被逐一访问(读取页里的记录):

在这里插入图片描述
在批量访问这些数据的时候,会被逐一插入到 young 区域头部:
在这里插入图片描述可以看到,原本在 young 区域的热点数据 6 和 7 号页都被淘汰了,这就是 Buffer Pool 污染的问题。

怎么解决出现 Buffer Pool 污染而导致缓存命中率下降的问题?

像前面这种全表扫描的查询,很多缓冲页其实只会被访问一次,但是它却只因为被访问了一次而进入到 young 区域,从而导致热点数据被替换了。

但是,LRU 链表中 young 区域就是热点数据,只要我们提高进入到 young 区域的门槛,就能有效地保证 young 区域里的热点数据不会被替换掉。

所以,MySQL 是这样做的:进入到 young 区域条件增加了一个停留在 old 区域的时间判断

具体是这样做的,在对某个处在 old 区域的缓存页进行第一次访问时,就在它对应的控制块中记录下来这个访问时间:

  • 如果后续的访问时间与第一次访问的时间在某个时间间隔内,那么该缓存页就不会被从 old 区域移动到 young 区域的头部
  • 如果后续的访问时间与第一次访问的时间不在某个时间间隔内,那么该缓存页移动到 young 区域的头部

这个间隔时间是由 innodb_old_blocks_time 控制的,默认是 1000 ms。

也就说,只有同时满足「被访问」与「在 old 区域停留时间超过 1 秒」两个条件,才会被插入到 young 区域头部,这样就解决了 Buffer Pool 污染的问题 。

另外,MySQL 针对 young 区域其实做了一个优化,为了防止 young 区域节点频繁移动到头部。young 区域前面 1/4 被访问不会移动到链表头部,只有后面的 3/4被访问了才会。

04、脏页什么时候会被刷入磁盘?

引入了 Buffer Pool 后,当修改数据时,首先是修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页,但是磁盘中还是原数据

因此,脏页需要被刷入磁盘,保证缓存和磁盘数据一致,但是若每次修改数据都刷入磁盘,则性能会很差,因此一般都会在一定时机进行批量刷盘

可能大家担心,如果在脏页还没有来得及刷入到磁盘时,MySQL 宕机了,不就丢失数据了吗?

这个不用担心,InnoDB 的更新操作采用的是Write Ahead Log(预写日志) 策略,即先写日志,再写入磁盘,通过 redo log 日志让 MySQL 拥有了崩溃恢复能力。

下面几种情况会触发脏页的刷新:

  • 当 redo log 日志满了的情况下,会主动触发脏页刷新到磁盘;
  • Buffer Pool 空间不足时,需要将一部分数据页淘汰掉,如果淘汰的是脏页,需要先将脏页同步到磁盘;
  • MySQL 认为空闲时,后台线程会定期将适量的脏页刷入到磁盘;
  • MySQL 正常关闭之前,会把所有的脏页刷入到磁盘;

在我们开启了慢 SQL 监控后,如果你发现「偶尔」会出现一些用时稍长的 SQL,这可能是因为脏页在刷新到磁盘时可能会给数据库带来性能开销,导致数据库操作抖动。

如果间断出现这种现象,就需要调大 Buffer Pool 空间或 redo log 日志的大小。

1.3 一条 select 语句的执行流程

现有一条查询语句:

select * from product where id = 1;

这条查询语句,在 MySQL 运行期间都发生了什么?

在这里插入图片描述
这张图是非常经典的一个执行流程图,从客户端建立起连接后,最主要的就是 Server 层和存储引擎层的交互,下面就来展开说一说每一个功能模块的作用:

1.3.1 连接器

连接器连接会经过三个步骤,只有上一步骤通过了才会继续往下执行:

  1. 建立连接:客户端连接 MySQL 服务,需要经过 TCP 三次握手,因为 MySQL 是基于 TCP 协议进行传输的,如果报错就说明连接失败;
  2. 校验用户身份:校验客户端的用户名和密码,如果用户名或密码错误,客户端的程序就结束执行;
  3. 获取权限:用户身份验证通过后,连接器就会获取该用户的权限保存起来,后续该用户在此连接里的任何操作都会基于连接开始时读取到的权限进行权限逻辑的判断。

所以,如果一个用户已经建立了连接,即使管理员中途修改了该用户的权限,也不会影响已经存在连接的权限。修改完成后,只有再新建的连接才会使用心得权限设置。

这里有几个问题:

如何查看 MySQL 服务被多少个客户端连接了?

可以执行命令来查看:

show processlist

在这里插入图片描述

其中有几列比如:User 表示哪个用户连接了 MySQL 服务,Command 表示当前用户执行的命令,Time 表示空闲时长。

空闲连接会一直占用着吗?

空闲连接不会一直占用着,MySQL 中定义了空闲连接的最大空闲时长,由 wait_timeout 参数控制的,默认值是 8 小时(28800秒),如果空闲连接超过了这个时间,连接器就会自动将它断开。

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

我们也可以自己手动断开空闲的连接,使用 kill connection + id 命令:

mysql> kill connection +6;
Query OK, 0 rows affected (0.00 sec)

注意:一个处于空闲状态的连接被服务端主动断开后,这个客户端并不会马上知道,而是等到客户端在发起下一个请求的时候才会收到报错信息:“ERROR 2013 (HY000): Lost connection to MySQL server during query”。

MySQL 的连接数有限制吗?

MySQL 服务支持的最大连接数由 max_connections 参数控制,如果超过这个值,系统就会拒绝接下来的连接请求,并报错提示:“Too many connections”。

MySQL 的连接与 HTTP 一样,也有长连接和短连接的概念:

# MySQL中的长连接和短连接
# 短连接
连接 mysql 服务(TCP 三次握手)
执行sql
断开 mysql 服务(TCP 四次挥手)
# 长连接
连接 mysql 服务(TCP 三次握手)
执行sql
执行sql
执行sql
....
断开 mysql 服务(TCP 四次挥手)


# HTTP中的长连接和短连接
# 长连接:
建立连接 — — 数据传输 — — 保持连接(心跳)— — 数据传输 — — 保持连接(心跳)… — — 关闭连接
# 短连接:
建立连接 — — 数据传输 — — 关闭连接…建立连接 — — 数据传输 — — 关闭连接

可以看到,使用长连接的好处就是可以减少建立连接和断开连接的过程,所以一般推荐使用长连接。

但是,使用长连接后可能会占用内存增多,因为 MySQL 在执行查询过程中临时使用内存管理连接对象,这些连接对象资源只有在连接断开时才会释放。如果长连接累计很多,将导致 MySQL 服务占用内存太大,有可能会被系统强制杀掉,这样会发生 MySQL 服务异常重启的现象。

如何解决长连接占用内存的问题?

有两种解决方式:

  • 第一种,定期断开长连接。既然断开连接后就会释放连接占用的内存资源,那么我们可以定期断开长连接。

  • 第二种,客户端主动重置连接。MySQL 5.7 版本实现了 mysql_reset_connection() 函数的接口(注意这是接口函数不是命令),那么当客户端执行了一个很大的操作后,在代码里调用 mysql_reset_connection 函数来重置连接,达到释放内存的效果。这个过程不需要重连和重新做权限验证,但是会将连接恢复到刚刚创建完时的状态。

1.3.2 查询缓存

连接器的工作完成后,客户端就可以向 MySQL 服务发送 SQL 语句了,MySQL 服务收到 SQL 语句后,就会解析出 SQL 语句的第一个字段,看看是什么类型的语句。

如果 SQL 是查询语句(select 语句),MySQL 就会先去查询缓存( Query Cache )里查找缓存数据,看看之前有没有执行过这一条命令,这个查询缓存是以 key-value 形式保存在内存中的,key 为 SQL 查询语句,value 为 SQL 语句查询的结果

如果查询的语句命中查询缓存,那么就会直接返回 value 给客户端。如果查询的语句没有命中查询缓存中,那么就要往下继续执行,等执行完后,查询的结果就会被存入查询缓存中。

这里需要说明的是,查询缓存缓存的不是查询计划,而是查询对应的结果。这就意味着查询匹配的鲁棒性大大降 低,只有相同的查询操作才会命中查询缓存。两个查询请求在任何字符上的不同(例如:空格、注释、大小写等),都会导致缓存不会命中。因此MySQL 的查询缓存命中率并不高

另外,MySQL 的缓存系统会监测涉及到的每张表,只要该表的结构或者数据被修改,比如对该表使用了 INSERT 、 UPDATE 、 DELETE 、 TRUNCATE TABLE 、 ALTER TABLE 、 DROP TABLE 或 DROP DATABASE 语句,那么使用该表的所有高速缓存查询都将变为无效并从高速缓存中删除!所以对于更新压力大的数据库来说,查询缓存的命中率会非常低。

所以,MySQL 8.0 版本直接将查询缓存删掉了,也就是说 MySQL 8.0 开始,执行一条 SQL 查询语句,不会再走到查询缓存这个阶段了

对于 MySQL 8.0 之前的版本,如果想关闭查询缓存,我们可以通过将参数 query_cache_type 设置成 DEMAND。

注意:
这里需要说明的是,查询缓存是 Server 层的,也就是 MySQL 8.0 版本移除的是 Server 层的查询缓存,并不是 Innodb 存储引擎中的 buffer pool。

1.3.3 解析器

在正式执行 SQL 查询语句之前,MySQL 会对 SQL 语句做解析,解析器会做两件事情:

  1. 词法解析

    MySQL 会根据我们输入的字符串识别出关键字,比如这条语句:

    select usernme, ismale from userinfo where age > 20 and level < 5 and 1 = 1;
    

    在分析之后,会得到 10 个 Token,其中有三个 keyword,分别为 select、from 和 where。

  2. 语法解析

    根据词法分析的结果,语法解析器会根据语法规则,判断我们输入的这个 SQL 语句是否满足 MySQL 语法,如果没问题就会构建出 SQL 语法树,这样方便后面模块获取 SQL 类型、表名、字段名、 where 条件等等。
    在这里插入图片描述
    如果我们输入的 SQL 语句语法不对,就会在解析器这个阶段报错。但需要注意的是,表不存在或者字段不存在,并不是在解析器里做的,解析器只负责检查语法和构建语法树,但是不会去查表或者字段存不存在。

1.3.4 执行器

经过了解析器解析、优化器优化后,接着才开始真正地执行 SQL 查询语句的流程了,每条 SELECT 查询语句流程主要可以分为三个阶段:

  • prepare 阶段,也就是预处理阶段;
  • optimize 阶段,也就是优化阶段;
  • execute 阶段,也就是执行阶段。

01、预处理器

预处理阶段大概做了两件事:

  1. 检查 SQL 查询语句中的表或者字段是否存在(如果不存在,就会在执行 SQL 查询语句的 prepare 阶段中报错);
  2. 将 select * 中的 * 符号扩展为表上的所有列。

02、优化器

经过预处理阶段后,还需要为 SQL 查询语句先制定一个执行计划(选择查询成本最小的计划),这个也是由优化器来完成的。

在优化器中会确定 SQL 语句的执行路径,比如是根据全表检索,还是根据索引检索等。我们可以使用 explain关键字来查看 SQL 语句的执行计划。

03、执行器

在执行器执行的过程中,它与存储引擎交互,此交互是以记录页为单位的。执行器和存储引擎的交互过程大概分为三部分:

  • 主键索引查询
  • 全表扫描
  • 索引下推

具体的可以参考链接:执行一条select语句,期间发生了什么

1.3.5 总结

执行一条 SQL 查询语句,期间发生了什么?大概有以下几个步骤:

  1. 连接器:建立连接,管理连接、校验用户身份;

  2. 查询缓存:查询语句如果命中查询缓存则直接返回,否则继续往下执行。MySQL 8.0 已删除该模块;

  3. 解析 SQL,通过解析器对 SQL 查询语句进行词法分析、语法分析,然后构建语法树,方便后续模块读取表名、字段、语句类型;

  4. 执行 SQL:执行 SQL 共有三个阶段:

    预处理阶段:检查表或字段是否存在;将 select * 中的 * 符号扩展为表上的所有列;
    优化阶段:基于查询成本的考虑, 选择查询成本最小的执行计划;
    执行阶段:根据执行计划执行 SQL 查询语句,从存储引擎读取记录,返回给客户端。

1.4 一条 update 语句的执行流程

在这里插入图片描述
大致的执行流程与 select 语句是一样的,这里需要注意存储引擎层存储和读取数据时记录日志阶段:

  1. 调用存储引擎接口后,会先从 Buffer Pool 获取数据页,如果没有就从磁盘中读入 Buffer Pool,然后判断更新前后的记录是否一样;

  2. 开启事务,修改数据之前先记录 undo log,写入 Buffer Pool 的 undo page;

  3. 开始更新 page data 中的记录,被修改的数据页称为脏页,修改会被记录到内存中的 redo log buffer 中,再刷盘到磁盘的 redo log 文件,此时事务是 perpare阶段;

  4. 这个时候更新就完成了,当时脏页不会立即写入磁盘,而是由后台线程完成,这里会用 double write 来保证脏页刷盘的可靠性;

  5. 还没结束呢,这时候可以通知 Server 层,可以正式提交数据了, 执行器记录 binlog cache,事务提交时才会将该事务中的 binglog 刷新到磁盘中;

  6. 这个时候 Update 语句完成了 Buffer Pool 中数据页的修改、undo 日志、redo log 缓存记录,以及记录 binlog cache 缓存;

  7. commit 阶段,这个阶段是将 redo log 中事务状态标记为 commit;

  8. 此时 binlog 和 redo log 都已经写入磁盘,如果触发了刷新脏页的操作,先把脏页 copy 到 double write buffer 里,Double Write Buffer 的内存数据刷到磁盘中的共享表空间 ibdata,再刷到数据磁盘上数据文件 ibd 中。

  9. 流程完结。

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MySQL高级 MySQL高级_思维导图.pdf 63.MySQL高级_主从复制.avi 62.MySQL高级_行锁总结.avi 61.MySQL高级_如何锁定一行.avi 60.MySQL高级_间隙锁危害.avi 59.MySQL高级_索引失效行锁变表锁.avi 58.MySQL高级_行锁演示答疑补充.avi 57.MySQL高级_行锁案例讲解.avi 56.MySQL高级_行锁理论.avi 55.MySQL高级_读锁案例讲解2.avi 54.MySQL高级_读锁案例讲解.avi 53.MySQL高级_数据库锁理论概述.avi 52.MySQL高级_全局查询日志.avi 51.MySQL高级_用Show Profile进行sql分析.avi 50.MySQL高级_批量插入数据脚本.avi 49.MySQL高级_慢查询日志.avi 48.MySQL高级_为排序使用索引OrderBy优化.avi 47.MySQL高级_in和exists.avi 46.MySQL高级_小表驱动大表.avi 45.MySQL高级_索引优化答疑补充和总结口诀.avi 44.MySQL高级_索引面试题分析.avi 43.MySQL高级_索引优化10.avi 42.MySQL高级_索引优化9.avi 41.MySQL高级_索引优化8.avi 40.MySQL高级_索引优化7.avi 39.MySQL高级_索引优化6.avi 38.MySQL高级_索引优化5.avi 37.MySQL高级_索引优化4.avi 36.MySQL高级_索引优化3.avi 35.MySQL高级_索引优化2.avi 34.MySQL高级_索引优化1.avi 33.MySQL高级_索引三表优化案例.avi 32.MySQL高级_索引两表优化案例.avi 31.MySQL高级_索引单表优化案例.avi 30.MySQL高级_explain之热身Case.avi 29.MySQL高级_explain之Extra介绍.avi 28.MySQL高级_explain之rows介绍.avi 27.MySQL高级_explain之ref介绍.avi 26.MySQL高级_explain之key_len介绍.avi 25.MySQL高级_explain之possible_keys和key介绍.avi 24.MySQL高级_explain之type介绍.avi 23.MySQL高级_explain之select_type和table介绍.avi 22.MySQL高级_explain之id介绍.avi 21.MySQL高级_explain使用简介.avi 20.MySQL高级_性能分析前提知识.avi 19.MySQL高级_哪些情况不适合建索引.avi 18.MySQL高级_哪些情况适合建索引.avi 17.MySQL高级_索引结构与检索原理.avi 16.MySQL高级_索引分类和建索引命令语句.avi 15.MySQL高级_索引优势劣势.avi 14.MySQL高级_索引是什么.avi 13.MySQL高级_七种JOIN的SQL编写.avi 12.MySQL高级_七种JOIN理论.avi 11.MySQL高级_SQL执行加载顺序.avi 10.MySQL高级_SQL性能下降原因.avi 09.MySQL高级_存储引擎简介.avi 08.MySQL高级_MySQL逻辑架构简介.avi 07.MySQL高级_MySQL配置文件.avi 06.MySQL高级_修改字符集.avi 05.MySQL高级_安装位置.avi 04.MySQL高级_ROOT密码设置和开机自启动.avi 03.MySQL高级__RPM安装.avi 02.MySQL高级_MySQL简介.avi 01.MySQL高级_课程简介.avi
第一部 MySQL基础入门(21节) 01-老男孩运维DBA课程开班.avi 02-数据库概念介绍.avi 03-数据库种类介绍及关系型数据库原理.avi 04-非关系型数据库介绍.avi 05-非关系型数据库种类介绍.avi 06-关系型数据库产品介绍01.avi 07-关系型数据库产品介绍02.avi 08-非关系型数据库产品介绍01.avi 09-数据库产品排名及发展大事记.avi 10-MySQL数据库产品介绍.avi 11-数据库基础内容小结.avi 12-为什么选择MySQL数据库MySQL优势介绍.avi 13-MySQL数据库分类与版本升级知识讲解.avi 14-MySQL数据库商业版与社区版区别.avi 15-MySQL数据库的发布版本知识讲解.avi 16-MySQL数据库发展的三条产品线介绍.avi 17-MySQL数据库发布版本命名知识介绍.avi 18-企业生产场景如何选择MySQL产品线产品及对应版本.avi 19-MySQL数据库企业生产常用5种安装方法介绍.avi 20-如何选择MySQL数据库版本及安装方式.avi 21-MySQL5.5编译方式安装实战.avi 第二部 MySQL多实例安装与企业应用场景(10节) 22-MySQL数据库多实例介绍.avi 23-MySQL数据库多实例的优势和问题介绍.avi 24-MySQL数据库多实例的门户企业应用场景.avi 25-MySQL数据库多实例的多种配置方案介绍.avi 26-MySQL数据库多实例安装实战讲解.avi 27-MySQL数据库多实例初始化及服务启动.avi 28-MySQL数据库多实例启动问题排错方法及实战排错.avi 29-MySQL数据库多实例实战排错02.avi 30-增加MySQL数据库第三个实例实战讲解.avi 31-MySQL数据库多实例的其他故障问题说明.avi 第三部:MySQL应用管理及进阶实战操作(29节) 01-MySQL启动与关闭深入知识及原理.avi 02-登录MySQL知识深入讲解.avi 03-学会使用MySQL数据库的帮助.avi 04-修改mysql密码多方法实战及注意-排错.avi 05-找回丢失的mysql密码实战.avi 06-多实例找回丢失的mysql密码.avi 07-SQL语言介绍及分类详解.avi 08-创建不同字符集数据库及企业场景应用讲解.avi 09-显示-连接-删除等数据库的库管理应用讲解.avi 10-创建mysql用户及授权的多种方法实战.avi 11-本地及远程主机授权思想及多种方法实战.avi 12-自己动手实战确定MySQL的授权权限列表.avi 13-生产场景如何授权用户及权限讲解.avi 14-MySQL建表语句及表的知识.avi 15-查看表结构以及建表语句.avi 16-索引的知识及索引创建多种方法实战.avi 17-索引生效的基本条件说明.avi 18-主键-唯一-普通索引创建及删除小结.avi 19-DML语句之insert知识讲解.avi 20-DQL之select知识实战讲解.avi 21-DQL之select多表连表查询实战.avi 22-利用explain查看sql语句的执行计划.avi 23-DML之修改表中的记录实战.avi 24-小试牛刀初步增量恢复MySQL数据实战.avi 25-某企业运维全套面试题解答.avi 26-DML之修改表及企业严重故障案例解决实战.avi 27-删除表中的数据机企业故障案例及防止方法.avi 28-增删改表的字段实战详解.avi 29-更改表名及删除表实战讲解.avi 第四部 MySQL乱码问题及字符集实战(14节) 01-MySQL数据乱码及多种解决方案实战1.avi 02-MySQL数据乱码及多种解决方案实战2.avi 03-MySQL不乱码5种方法及不乱码根源深入详解.avi 04-下节内容及课后作业说明.avi 05-课前思想-17期学生23万入职BAT公司 06-课前思想-及课前考试题说明.avi 07-MySQL字符集介绍及生产常用字符集说明.avi 08-MySQL不同字符集区别及企业生产选择.avi 09-MySQL乱码原因开始系统影响揭秘.avi 10-MySQL执行set names到底做了什么?.avi 11-MySQL命令带字符集导入到底做了什么?.avi 12-MySQL数据中文不乱码终极实战.avi 13-MySQL数据中文不乱码终极大总结.avi 14-更改生产线上MySQL数据字符集的方案讲解.avi 第五部 MySQL备份、增量备份及数据恢复基础实战(12节) 01-备份数据的意义及重要性.avi 02-mysqldump多个命令参数备份实战.avi 03-mysqldump逻辑备份的工作原理.avi 04-备份多个库的思想及多种方法讲解.avi 05-mysql单多表的备份实战及脚本批量备份讲解.avi 06-只备份MySQL表结构及只备份MySQL数据.avi 07-企业生产场景不同引擎备份命令参数详解.avi 08-利用source恢复mysql数据讲解及实战.avi 09-分库备份后mysql如何分库恢复实战.avi 10-mysql进程-状态-在线修改参数重要知识讲解.avi 11-mysqlbinlog命令介绍及实战讲解.avi 12-mysqldump-master-data参数答疑详解.avi 第六部 MySQL主从复制原理及实战部署(10节) 01-由架构因为引出主从复制的作用及重要性.avi 02-文件及DB各种同步方案大集合介绍讲解.avi 03-mysql主从复制介绍及分布式数据库架构实现介绍.avi 04-主从同步的应用场景及切换从库不丢数据多方案介绍.avi 05-mysql数据库读写分离介绍及企业生产实现方案.avi 06-根据企业业务拆分业务应用到不同的从库思想.avi 07-mysql主从复制原理画图深入浅出讲解.avi 08-mysql主从复制实战01.avi 09-mysql主从复制实战02.avi 10-主从复制的超简单实现方案说明.avi 第七部 MySQL主从复制企业级深入高级应用实战(20节) 01-MySQL主从复制原理画图口头考试讲解.avi 02-课前思想-企业面试必胜绝招讲解.avi 03-MySQL主从复制故障多个案例实战讲解.avi 04-回顾MySQL主从复制配置步骤及注意事项.avi 05-回顾MySQL主从复制原理要点.avi 06-企业场景MySQL主从复制最牛部署方案.avi 07-一键获取全备及binlog位置多种方案讲解.avi 08-不停主库一键批量配置MySQL主从复制方案.avi 09-MySQL主从复制3个线程状态信息讲解.avi 10-MySQL主从复制读写分离授权多种方案案例详解.avi 11-忽略MySQL主从复制主库授权表同步实战.avi 12-MySQL主从复制指定不同库表同步参数说明.avi 13-MySQL主从复制从库只读案例实战及原理总结.avi 14-企业生产场景MySQL主从复制故障原因及实战解决.avi 15-从库开启BINLOG原因及开启实战讲解1.avi 16-从库开启BINLOG原因及开启实战讲解2.avi 17-企业场景一主多从宕机从库切换主继续和从同步过程详解1.avi 18-企业场景一主多从宕机从库切换主继续和从同步过程详解2.avi 19-企业场景一主多从宕机从库宕机解决.avi 20--企业场景-双主及多主同步过程详解及企业选用方案说明.avi 第八部-老男孩MySQL备份与恢复实战案例及生产方案(10节) 01-全量及增量备份概念及优缺点详解 02-不同企业如何选择备份方案及备份需要恢复的场景分析 03-企业场景数据库需要增量恢复的条件分析 04-MySQL数据恢复的必要条件及恢复案例场景图解分析 05-实战模拟企业数据丢失应用的案例场景 06-MySQL数据库增量恢复详细实战 07-更多MySQL数据库增量恢复大讨论及大总结 08-MySQL增量恢复小结及核心恢复思想 09-课后自学能力作业-务必完成并分享讲解 10-内部学员技术大会分享课表说明 第九部-老男孩MySQL服务日志详细介绍及增量恢复命令实践(7节) 01-mysqlbinlog命令介绍及实战讲解 02-mysqldump-master-data参数答疑详解 03-MySQL服务错误日志介绍及实践 04-MySQL服务普通查询日志介绍及实践 05-MySQL服务慢查询日志介绍及实践 06-MySQL服务二进制日志的3种工作模式详细介绍 07-MySQL服务二进制日志的3种工作模式配置方法实战 第十部-老男孩MySQL常用引擎及优缺点-应用场景-调优详解(14节) 01-MySQL服务存储引擎介绍 02-MySQL服务存储引擎体系结构 03-MySQL服务MyISAM引擎介绍及磁盘文件格式 04-MySQL服务事务详细介绍及ACID特性说明 05-MySQL服务MyISAM引擎特点讲解 06-MySQL服务MyISAM引擎适合的生产应用场景 07-MySQL服务MyISAM引擎调优精要 08-MySQL服务InnoDB引擎介绍及磁盘文件格式 09-MySQL服务InnoDB引擎特点讲解 10-MySQL服务InnoDB引擎适合的生产应用场景 11-MySQL服务InnoDB引擎调优及不同引擎功能对比 12-MySQL服务引擎种类功能及对应参数配置说明 13-批量修改MySQL服务引擎的多种方案 14-有关MySQL服务存储引擎的面试题等说明 第十一部 MySQL读写分离开发实现及软件实现-物理备份-高可用(已经包含有5节视频+文档资料) 01-amoeba读写分离实现技术分享.avi 02-mysql-proxy读写分离实现技术分享.avi 03-PHP程序实现读写分离技术分享.avi 04-xtrabackup热备工具技术分享.avi 05-mysql-mmm高可用实现技术分享.avi 文档资料 01-mysql-mmm高可用架构-王雄.rar 02-mysql半主从同步-技术分享--余宏刚.rar 03-xtrabackup安装及操作文档-技术分享--王玉晓.rar 04-mysql主从通过mysql-proxy程序实现读写分离.doc 老男孩linux测试读写分离php网站源代码.zip 第十二部 MySQL高可用工具heartbeat实战(33节) 01-heartbeat介绍与作用.avi 02-Heartbeat的工作原理与服务切换条件.avi 03-Heartbeat心跳连接介绍.avi 04-裂脑的概念讲解.avi 05-裂脑发生的多种原因介绍.avi 06-防止裂脑发生的8种秘籍01.avi 07-防止裂脑发生的8种秘籍02.avi 08-防止裂脑发生的8种秘籍03.avi 09-有关fence设备和仲裁机制说明.avi 10-heartbeat的消息类型介绍.avi 11-heartbeat的IP接管和故障转移原理.avi 12-高可用软件的IP配置管理技术讲解.avi 13-heartbeat的默认路径配置介绍.avi 14-heartbeat的软件版本分支说明.avi 15-heartbeat企业应用场景介绍.avi 16-部署heartbeat高可用业务需求描述.avi 17-模拟服务器准备及IP配置说明.avi 18-配置主机名及服务器hosts文件解析.avi 19-配置服务器间心跳的连接.avi 20-安装heartbeat软件及配置文件讲解.avi 21-heartbeat的主要配置文件参数讲解.avi 22-实战配置heartbeat配置文件.avi 23-启动heartbeat服务并查看配置的VIP.avi 24-发生裂脑故障及根据前面原理排查思路.avi 25-通过heartbeat日志分析接管过程.avi 26-heartbeat实现web服务高可用实战案例1.avi 27-heartbeat实现web服务高可用实战案例1原理.avi 28-heartbeat实现web服务高可用案例2.avi 29-有关heartbeat调用资源的生产场景应用.avi 30-heartbeat高可用案例拓展.avi 31-heartbeat和keepalived的应用场景区别.avi 32-heartbeat服务生产环境下维护要点.avi 33-heartbeat服务生产环境维护FAQ.avi 第十三部 MySQL高可用工具drbd实战(18节) 01-drbd服务介绍.avi 02-drbd的工作原理介绍.avi 03-drbd的工作原理图.avi 04-drbd的复制协议与应用模式.avi 05-drbd的企业应用场景介绍.avi 06-常见运维同步工具介绍.avi 07-drbd的部署及ip配置规划.avi 08-drbd软件的安装配置准备.avi 09-创建同步的分区实践drbd.avi 10-drbd环境分区说明及分区命令.avi 11-实际安装drbd软件实战.avi 12-drbd相关配置列表说明.avi 13-配置drbd加载到内核模块.avi 14-drbd配置文件参数讲解及实际配置.avi 15-drbd服务初始化数据故障机排查过程.avi 16-启动drbd并配置主从同步数据.avi 17-drbd服务的常见故障及排查方法.avi 18-挂载测试数据库同步及查看备节点数据.avi 第十四部 MySQL高可用综合实战(完整版32节) 01-重要课前思想mp4 02-MySQL高可用需求与架构讲解mp4 03-大规模集群架构MySQL高可用的位置和架构mp4 04-MySQL高可用实战模拟环境描述mp4 05-MySQL高可用生产场景配置及网络地址规划mp4 06-MySQL高可用实施正式环境准备与裂脑注意mp4 07-快速安装双机Centos6.4下heartbeat并配置启动mp4 08-快速安装双机Centos6.4下drbd服务准备01mp4 09-快速安装双机Centos6.4下drbd服务实战02mp4 10-详解drbd服务状态信息细节mp4 11-启动服务测试DRBD实际同步情况mp4 12--配合heartbeat调试drbd服务配置mp4 13-MySQL服务安装实战安装过程讲解mp4 14-一键安装Mysql多实例实战讲解与演示mp4 15-通过手工测试MySQL的高可用切换mp4 16-MySQL双主高可用自动切换实战实现mp4 17-有关MySQL双主高可用my.cnf的配置注意事项讲解mp4 18-MySQL高可用切换的重要思想原理及故障排除思想、mp4 19-MySQL主从同步一键安装脚本实战mp4 20-MySQL多主多从高可用集群自动切换实现mp4 21-有关MySQL高可用注意及常见故障讲解mp4 22-MySQL集群及高可用的更多思路方案引子mp4 23-常见MySQL集群高可用架构讲座01.mp4 24-常见MySQL集群高可用架构讲座02.mp4 25-常见MySQL集群高可用架构讲座03.mp4 26-常见MySQL集群高可用架构讲座04.mp4 27-常见MySQL集群高可用架构讲座05.mp4 28-门户分布式数据库架构案例分享01.mp4 29-门户分布式数据库架构案例分享02.mp4 30-门户分布式数据库架构案例分享03.mp4 31-门户分布式数据库架构案例分享04.mp4 32-门户分布式数据库架构案例分享05.mp4 第十五部 MySQL数据库优化思想与优化实战(9节) 1-网站打开慢mysql问题多解决方案企业案例.avi 2-MySQL索引优化要点精讲01 3-MySQL索引优化生产案例讲解02 4-linux运维人员必须掌握的核心经验案例.avi MySQL数据库生产场景核心优化精讲 5-MySQL数据库硬件优化生产方案及细节精讲01.avi 6-MySQL数据库系统优化生产方案及细节精讲02.avi 7-MySQL数据库参数索引优化生产方案及细节精讲03.avi 8-MySQL数据库SQL优化生产方案及细节精讲04.avi 9-MySQL数据库架构优化生产方案及细节精讲05.avi 第十六部 MySQL业务变更流程与安全管理思想(7节) 01-安全优化-项目开发流程及数据库更新流程.avi 02-DBA参与项目数据库设计及培训开发人员高效设计MYSQL库语句.avi 03-老男孩核心思想-项目周期的制定思想.avi 04-linux进程占用cpu高的解决方案案例.avi 05-数据库账户权限控制多种思路及技巧.avi 06-数据库客户端安全控制策略详解.avi 07-数据库运维的核心管理思想.avi
MySQL 进阶实战》是一本探讨MySQL数据库高级应用和实战技巧的书籍。MySQL是一种广泛使用的开源关系型数据库管理系统,在Web开发和数据分析等领域有着重要的应用。 《MySQL 进阶实战》将帮助读者理解MySQL的高级功能和最佳实践,进一步优化数据库的性能和稳定性。本书主要内容包括: 1. 高级查询优化:介绍如何使用索引、列存储和分区技术来提高查询性能,避免慢查询和死锁等问题。 2. 数据库设计与架构:详细讲解如何设计合理的数据库模型,包括表关系、数据类型和字段命名规范,以及应对高并发和大数据量的应用场景。 3. 高可用与备份恢复:介绍如何设置主从复制、集群和故障切换,确保数据库的高可用性和数据安全。 4. 性能调优与监控:介绍如何使用工具和技术调优MySQL数据库的性能,包括查询优化、缓存设置和资源管理等方面。 5. 安全与权限管理:详细讲解如何设置数据库的用户权限、访问控制和加密保护,防止非法访问和数据泄露。 6. MySQL新特性与实践:介绍新版本MySQL的特性和改进,以及如何应用到实际项目中。 《MySQL 进阶实战》不仅适合已经具有一定MySQL基础知识的读者,也可以作为MySQL数据库开发和运维人员的参考手册。通过读此书,读者将能够更深入地了解和应用MySQL数据库,在实际项目中提高开发和管理效率,提升数据库的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值