Mysql学习

1、了解MySQL架构
关系型数据库,结构化查询语句。
关系型数据库基于表去维护的,格式是一致的,可以统一用sql语言去操作,没有kv结构灵活,性能也没有那么高。

系统库
mysql,系统信息表。如权限、插件、主题、帮助。
information_schema,日志、innodb等数据、线程。
performance_schema,

2、一条sql执行要需要什么?

  1. 跟服务器建立连接
    1. 变量来管理连接
      Threads_cached 缓存线程数
      Threads_created 打开线程数(show full processlist , 删除链接kill xxxx)
    2. 配置(set @@GLOBAL.max_connections=10;)
      max_connections 服务最大的开启数(默认151)
      wait_timeout 等待时间,超过则关闭(默认8小时)。
  2. 解析器:词法+语法解析器
  3. 预处理:提供该功能,但可以控制是否使用
    (prepare pre_product from ‘select * from product where name=?’;)
    (set @name=’OR 1=1 —‘)
    (execute pre_product using @name)
    1. 可以提升性能:预处理了sql语句,只需要配置参数即可
    2. 防止sql注入:因为参数化执行,不是拼接参数
  4. 优化器:基于服务最快方式执行语句,基于内存、cpu消化等情况
    1. 可配置--optimizer_switch
      (select @@optimizer_switch)
  5. 执行器
    存储成:用来真正存执行、储数据,基于不同存储引擎来做不同的操作(相当于插件)。
    (select @@datadir)

3、innoDB储存引擎
会保存到磁盘,并且每个表都会有一个ibd文件。
表空间:数据如何存储到磁盘的。

独立表空间:每个表都有一个独立的ibd数据文件(默认开启select @@innodb_file_per_table)
系统表空间:所有的表数据都在一个文件或多个指定文件,ibdata文件(innodb_data_file_path)
通用表空间:可以自己指定哪个表到哪个文件(create tablespace huihui_namespace datafile add ‘/path/path.ibd’ engine=innodb)

文件如何保存的?
最底层、原子单位为行、row。不是通过row直接保存文件的。
page页,class结构,里面保存的是行数据,page是保存到文件里面的。页的大小数是可以设置的(innodb_page_size,默认16k)。一个page页能保存的行数据也是有大小的,行为4k,这一页保存4行数据
extent区 会有很多的page页,默认64个page页
segement段,分为数据段、索引段、目录段等

bufferpool 内存区间,防止每次实时的跟磁盘进行交互。
假如:select where id=5的数据
之前,每次查询都需要与磁盘进行IO
之后,先判断bufferpool有木有这个数据,如果有直接返回,如果没有才需要到磁盘进行交互,并且保存到bufferpool。保存的数据所在的page页。

bufferpool与磁盘的交互最小单位是整个page页,默认是128M。(innodb_bufferpool_size)

内存和磁盘的一致性问题
改数据就会有先后顺序问题。

  1. 只更改内存,然后异步的方式去同步到磁盘,改了内存的数据,如果还没有同步到磁盘,那么这个页叫做脏页(数据和磁盘不一致的页)。(刷脏 innodb_page_cleaners)
    刷脏逻辑:
    1. 自适应,根据脏页产生的频率来修改刷脏的频率,这里也有很多配置
    2. redolog自适应,如果快满了则会刷脏
    3. 空闲的时候会去刷脏,每次刷脏的百分比
    4. 服务正常关闭,肯定会保证脏页能够保存到磁盘
    5. 如果内存没有同步到磁盘数据,则会根据redolog日志恢复,redolog只要去保存内存跟内存磁盘不一致的数据就可以了,redolog是同步的。redolog保证了数据修改。
    6. 结构 type | spaceId | page number | 修改数据
    7. redolog只保存在磁盘中,(innodb_red_log_capacity文件大小),拆分成不同文件保存不同的位置默认32个。如果过多则会覆盖。
    8. redolog数据为顺序io,因此速度较快。另外page页太大,因此数据交互量大
    9. 根据redolog,提供redolog buffer,先保存到内存里面。提供了选择(select @@innodb_flush_log_at_trx_commit; 1必须刷新到磁盘才能成功 0每秒刷新一次 2交给操作系统刷新)

1、何为索引,解决了什么问题?
提升性能
能够根据特定的列(多个)来提高查询的性能

查询索引
hash(k-v):memory 根据单条去查询是不是非常快,但是不支持范围查询
B+:innodb,myisam

索引原理
这个页的数据是排序好的,并且每行数据是一个单链链表,能够在某个页里面快速找到数据
二分法。 有序

page,是内存和磁盘交互的最小单元,因此需要跟磁盘交互非常大的次数,导致磁盘io开销大,影响了性能。
索引的作用能够快速根据字段来查询,空间换时间。
遍历的页数,只跟这个数的层级有关,并且层级越低io次数越少,因此为什么不用二叉树,因为层数过高导致次数过多。
B+树 比较稳定,都需要较小的次数完成
B树 同样的层级,放的数据越少,同样的数据量我的树的层级越高
但是不一定比B+树慢,但是整体慢。

B+树默认是需要排序的。因为主键id是一定有 序的,唯一的,因此都会基于主键id创建一个这样的索引书,主键、聚集、聚簇索引树,并且这个树下的叶子节点会有我们完整的数据。即使没有主键,也会默认的row_id来创建索引。
二级索引,
单列二级索引:除了主键索引都是二级索引,但是没有这行数据完整数据row,只包含主键id。可以重复
联合二级索引:先根据第一个字段排,相等则根据第二个排。

索引失效
回表

覆盖索引

2、从设计者角度来理解索引为何用B+树

3、二级索引、覆盖索引、主键索引、回表概念一网打尽

4、通过面试题来举一反三

MySQL 8.0 版本以后,一条 SQL 的执行流程大致如下所示:

  1. 解析器(Parser):该阶段将客户端发送的 SQL 查询文本进行解析,将其转换为内部数据结构。解析器会验证语法的正确性,并生成语法树或其他数据结构。
  2. 预处理器(Preprocessor):在这个阶段,MySQL 会进行一些前处理工作,如展开视图、执行宏替换等。这是为了准备查询进入优化器阶段。
  3. 优化器(Optimizer):这是查询执行过程中的关键阶段。优化器会基于查询的内部表示,考虑多个执行计划,选择最优的执行计划。这个阶段会决定查询如何访问表、使用索引、连接表以及执行其他操作。
  4. 执行计划生成(Execution Plan Generation):在优化器选择了最优执行计划后,会生成执行计划。执行计划是一个指令序列,描述了查询的具体执行步骤,包括表的访问顺序、连接方法、索引使用等。
  5. 执行器(Executor):执行器根据优化器生成的执行计划,实际执行查询操作。它从存储引擎中获取数据,并进行必要的操作,如排序、过滤等。
  6. 存储引擎(Storage Engine):存储引擎负责底层数据的存储和检索。在执行器的指导下,存储引擎执行实际的数据操作,如表扫描、索引搜索等。
  7. 磁盘访问(Disk Access):存储引擎可能需要从磁盘读取数据或写入数据。这包括了从磁盘加载表数据、索引,以及将修改写回磁盘等操作。

需要注意的是,MySQL 8.0 版本以后,优化器、执行计划生成和存储引擎之间的交互更加紧密,优化器可以通过存储引擎提供的统计信息和特性来做出更准确的决策。此外,MySQL 8.0 也引入了一些新的优化和特性,以提高查询性能和可靠性。上述流程中的每个阶段都可以涉及许多复杂的内部操作和优化,以便更高效地执行查询。