彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系

1. MySQL架构体系

show processlist
查看MySQL的所有连接状态,如果开启的连接太多,可以关闭一些
MySQL服务器启动之后,我们通常实在客户端编写SQL代码,客户端比如有JDBC,Navicat,cli

当我们在客户端写入一条语句:select * from table where id = 10 ;MySQL服务器端是如何运作的呢?

首先MySQL会有一个连接器,用来验证用户名和密码,验证通过了之后会有一个分析器,用来对输入进来的这条语句进行语法分析和词法分析,怎么实现的呢,有一个组件专门做词法分析和语法分析的组件,一个开源框架antlr,是一个分词器;还有一个Apache提供的一个专门做词法分析和语法分析的组件Calcite,标准的SQL解析器和JBDC驱动
彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第1张图片
除了分析器还有一个优化器
如果查找的表有多个,或者有多个索引,不知道该查哪个表,还有其他的情况,就会用到优化器
比如这个语句
优化器有两个组件,RBO,CBO
RBO基于规则优化,CBO基于成本的优化
彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第2张图片
优化器完成之后还有一个组件叫执行器,用来跟我们对应的一些存储引擎进行交互
执行器下面就是存储引擎,比如我们常见的innodb,myisam

2. MySQL存储引擎

存储引擎就是不同的数据文件在磁盘的不同组织形式
彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第3张图片
在MySQL里我们看到的是一张一张的表格,但是存储在磁盘里是一个一个的文件,我们的表用不同的存储引擎,在电脑里保存的文件后缀不一样
如果用innodb存储引擎保存的表在电脑里保存的文件后缀是frm,ibd ,frm存的是表结构数据,ibd存的是数据和索引,是聚集索引,表的数据和索引是一起保存的
在这里插入图片描述

如果用myisam存储引擎保存的表在电脑里保存的文件后缀是frm,MYD,MYI, frm存的是表结构数据, D是data的意思 MYD存的是表的数据, I是index的意思 MYI存的是索引数据
myisam存储引擎是非聚集索引,表数据和索引是分开保存的
在这里插入图片描述
show engines可以查看MySQL所有的存储引擎,要根据不同的场景选择不同的存储引擎,不同的场景对性能和效率都是有要求的。
彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第4张图片
如果什么也不设置,MySQL默认的存储引擎是innodb。
他俩的区别有:

  1. innodb支持事务,myisam不支持
  2. innodb有外键,myisam没有
  3. innodb支持表锁和行锁,myisam只支持表锁
  4. 索引存储的叶子节点数据不同
  5. count(*) myisam比较快,不能带任何查询条件

MySQL优化不仅仅是修改SQL语句,了解了MySQL底层架构时候可以有更多的地方进行优化。

3. MySQL索引

索引类似于字典一样,提高查找速度的,如果是你的话,会如何设计索引?
有关于索引,常见有哪些问题

  1. 索引是存储在文件中还是内存里?
    索引必须要进行持久化存储,除了memory这种存储引擎。索引是存在磁盘里,存在文件中的,
  2. 如果一旦放在文件里,索引在进行数据读取的时候,需要返回什么样的信息?
    每次在进行磁盘IO的时候,速度都比较慢,如果比较慢,怎么解决这个问题,解决问题的方式有两个,减少IO的次数,减少IO的量。
    索引在读取的时候,需要返回什么样的信息,首先需要有key值,其次需要返回一个文件名称,保存在哪个文件中,还需要知道offset,偏移量。
  3. 大数据hive就是这样存储的,但是MySQL不使用呢?
    因为慢,MySQL和hive涉及到两个不同的概念:OLTP和OLAP
    OLTP是联机事务处理,关系型数据库都归于这个,时效性高
    OLAP是联机分析处理,数据仓库归于这个,对历史数据进行分析,产生决策性影响
    彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第5张图片
  4. 那MySQL怎么设计索引系统呢?
    要先想清楚自己保存的数据格式是什么,k-v格式
    用什么样的数据结构用来存储呢,hash、二叉树、B+树等都可以存储键值对类型的数据。
  5. MySQL采用什么样的数据结构呢?为什么?
    MySQL官网已经列出来了,大部分索引是用B+树数据结构来存储的。
    彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第6张图片
    hash、B树
    我们怎么看一张表的索引存储结构是什么呢?
    show index from table执行命令
    什么时候用hash,什么时候用B树,跟我们使用什么样的存储引擎是相关的

innodb、myisam使用的是B树(但是本质是B+树)同时innodb支持自适应hash。
memory存储引擎使用的是hash数据结构

数据结构的选择

为什么innodb不能用hash?

hash散列严重,需要良好的hash算法
hash表需要大量的内存
不适合范围查询,不适合大量查询的场景

树有哪几种
BST:二叉搜索树
AVL:二叉平衡树
红黑树
B树
B+ 树
为什么选择B+ 树,其他树为什么不可以?
BST:二叉搜索树
彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第7张图片
如果插入的顺序是递增的,容易变成链表
彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第8张图片
因为它有可能退化成链表,并不是一颗平衡树。
AVL:二叉平衡树
二叉平衡树会根据插入的数据进行平衡、旋转
插入消耗
损失了一部分数据插入的性能带来了查询性能的提升
二叉平衡树保证最长路径和最短路径层数不超过1
彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第9张图片
红黑树:也是一种二叉平衡树
最长路径和最短路径只要不超过2倍就行

二叉平衡树和红黑树的对比
彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第10张图片
红黑树随着插入的数据越来越多,树越来越高,IO次数会变得越来越多
为什么会逐渐加深,因为每一个节点有且只有2个分支,所以不论BST、AVL、红黑树,随着插入的数据越来越多,树都会越来越深。
B树
彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第11张图片
我们在往里存数据的时候,就会和操作系统打交道,这里我们了解
两个基本的理论前提
局部性原理:空间和时间,数据程序聚集存放,刚刚被查询过的数据有可能很快又被查询
磁盘预读:内存跟磁盘进行交互的时候,有一个最小的逻辑单元,称之为页,页的大小一般是4k,或者8k,而在进行数据交互的时候,也是以页为单位的,可以是页的整数倍。innodb存储引擎默认读取16k
B树和B+ 树的区别

在这里插入图片描述
B+树能够存储的数据行数比B树的量级要大
为了能够保证索引能够存储的行数要多,就要控制key值的存储大小,是用int还是varchar,用int比较好

1、InnoDB是通过B+Tree结构对主键创建索引,然后叶子节点中存储记录,如果没有主键,那么会选择唯一键,如果没有唯一键,那么会生成一个6字节的row_id来作为主键
2、如果创建索引的键是其他字段,那么在叶子节点中存储的是该记录的主键,然后再通过主键索引找到对应的记录,叫做回表

聚簇索引和非聚簇索引

聚簇索引:数据和索引存放在一起
一个表的聚簇索引一定是主键吗?不一定
一个表的聚簇索引只有一个吗?是的
主键索引一定是聚簇索引吗?假如创建数据的时候没有主键,没有唯一键,添加数据之后,设置了主键
如果创建表的时候没有设置主键,会创建一个6个字节的rowid的索引,当设置主键后,会覆盖掉初始化的rowid索引。

索引的分类:

  1. 主键索引
  2. 唯一索引
  3. 普通索引/辅助索引/二级索引
    假如有一个表test
    id:主键     name:普通索引     age:int    sex:varchar
    语句:select * from test where name=“zhangsan”
    会检索两颗B+ 树,先从name树中找到id值,再从id树中找到整行的记录,这种是回表。
    select id,name from test where name=“zhangsan”
    通过name这颗树可以找到查询的所有字段,可以直接返回,不需要从主键树中检索结果,此时叫索引覆盖。
    常见的两个概念:
    回表
    如果创建索引的键是其他字段,那么在叶子节点中存储的是该记录的主键,然后再通过主键索引找到对应的记录,叫做回表
    索引覆盖
    两种方式哪个比较好,当然是索引覆盖比较好。
    MySQL优化的时候减少用回表。
    看MySQL的执行计划extra,如果有using index 就是使用了索引覆盖
    explain select。。。语句查看执行计划
  4. 全文索引
  5. 组合索引/联合索引
    索引如果包含多个字段,就是组合索引
    优化器会调整语句的顺序
    了解2个概念
    最左匹配
    当一个表的全部列都是索引列,不符合我们的最左匹配原则
    索引下推
    索引下推在非主键索引上的优化,可以有效减少回表的次数,大大提升了查询的效率

一般情况下,sql语句中尽可能多的带主键字段,方便进行查询,但是主键字段的条件一定会生效吗?
不一定
MySQL常用的命令
show index from table查看表的所用

select t1.name,t2.name from t1 join t2 on t1.id = t2.id
执行方式:
1、将两张表按照id字段进行关联,然后获取到对应的数据
2、把两个表需要的字段取出米,然后再进行关联
哪种方式IO量少
select * from test where name=zhangsan and age =18;
在5.7版本之前是这么执行的:
执行器从存储引擎中根据name的条件获取到所有的结果,然后将结果在执行器中按照age进行条件过滤
5.7引入索引下推之后是这么执行的:
根据name和age两个条件从存储引擎中做数据筛选,选出对应的结果
当执行计划出现了using index condition就是出现了索引下推

锁的概念

彻底搞懂MySQL索引机制,MySQL索引优化——MySQL架构体系_第12张图片

你可能感兴趣的:(mysql,架构)