mysql数据库底层数据结构和逻辑

MySQL调优

1、如果不存在这个索引MySQL效率的问题

MySQL 本身是基于文件系统的
MySQL本身的数据是存储到硬盘上的 文件中的
   
   1、就是基于INNODB引擎的是两个文件
      .frm:存储的是表的结构信息
      .ibd:数据和索引信息
      
   2、基于MyISAM存储引擎的
      三个文件
      存储的是 表结构信息
      存储的是 数据信息
      存储的是 索引信息
     

一条SQL语句的执行流程?

我们经常使用 SQLyog  Java代码  CMD命令行去操作我们的数据库 
哪现在我想问个问题
SQLYog  Java代码  CMD 他们三个的共同点是啥? 也就是说他们三个究竟干了什么事情?

他们的共同点就是将SQL语句 发送到 数据库的管理系统=====>没有执行SQL的功能 只有创建连接  发送SQL


MySQL就是基于文件系统的
我们想一个问题
基于文件系统 如果是我们要查询数据 我们怎么查询呢?
我们要到硬盘上去找一个文件 或者 一个人文件 会经过哪些过程?
  计算机在找东西的时候都要经过两个过程去定位资源
  1、磁盘的旋转
  2、磁盘的寻道
  
  所以我们在找一个数据的时候 时间=磁盘的旋转时间+磁盘的寻道时间
  一般情况下 磁盘的旋转时间是很短的  长的是磁盘的寻道(找内容)
  我们在查询MySQL中数据的时候 常时间的是 磁盘的寻道
  

MySQL:MySQL可以看成是一本书  拥有很多页面的这样一本书
我们如果要去这个书上去寻找东西------------>书的目录去寻找 应该是最快的
索引本身 就相当于是这本书的目录 如果这本书本身没有目录 那么我们的查询显然就效率就很低

mysql数据库底层数据结构和逻辑_第1张图片

mysql数据库底层数据结构和逻辑_第2张图片

2、索引的基本使用

INNODB表默认是会给咋们的主键创建索引的


CREATE TABLE t_dept(
  id INTEGER PRIMARY KEY AUTO_INCREMENT,
  deptName VARCHAR(50),
  deptDes VARCHAR(200),
  INDEX (deptName)
)

ALTER TABLE t_dept ADD INDEX (deptName,deptDes); 

有多个索引 那么就要创建多少个索引树

这个索引树 也是存储在 硬盘上的 我们在进行读取的时候还是  IO操作

波波老师我们查询全表的是IO操作   我们读取索引的时候也是 IO操作 那么你确定索引就能提高效率吗?

  假设现在我们要进行数据的获取 
  1kb的内容----->表的内容  1000条
  lKB的索引树的内容--10W  
  还有一个最重要的原因----索引引入了 数据结构来提高查询效率

3、索引底层的数据结构

3.1、索引的底层为什么不使用二叉树

如果是在极端的情况下 我们的节点 会全部 插入到 右边节点 如果是我们要遍历最后一个节点是不是相当于要将整个树所有的节点 遍历一次 这样的话 效率很低

mysql数据库底层数据结构和逻辑_第3张图片

3.2、索引的底层为什么不使用红黑树

红黑树 相比较于二叉树而言 效率就要更高一些了

红黑树 只要达到了条件树就会自动的旋转实现平衡 如果是我们同样要去查询 6这个节点的话那么 只需要查询四次就可以了 他的效率虽然要高于我们的 二叉树 但是如果是数据量特别大的话 那么整个树的节点遍历依然很高 效率偏低

mysql数据库底层数据结构和逻辑_第4张图片

3.3、索引的底层为什么不使用B树
在B树中  我们有个深度这个概念 
他就彻底的打破了二叉树  红黑树 一个节点上 只能存储 一个数据的这个限制  
深度的含义:一个节点上 最多存储的数据格式的最大的大小-1

在我们的B树的设计上 之所以要在一个节点上 设计多个数据 是因为 我们在遍历相同的数据的时候B树遍历的节点更少
而且本身还是有先后顺序进行排序的

B树最大的缺点是不适合做范围内的查询 
因为设计到范围内的查询的时候 还是要遍历所有的节点

mysql数据库底层数据结构和逻辑_第5张图片

3.4、索引的底层为什么使用的是B+树
B+树的所有的数据都存储到了 叶子节点 
存在冗余节点 以空间换时间来提高效率  而且在叶子节点上 所有的节点之间都存在 双向链表 他就能有效的解决范围内的查询

他继承了 B树一个几点上存储多条数据的优点  而且还将所有数据 都放到了叶子节点上  叶子节点之间通过双向链表来进行存储

mysql数据库底层数据结构和逻辑_第6张图片

4、索引的最左前缀原理

主键索引也被称为聚簇索引和普通索引


select * from t_dept where username=xxxxx

  如果是扫描索引树的话
  首先要扫描二级索引树========>找到xxxx对应的主键
  再扫描主键索引树-------.整到整条数据
  
 扫描全表 
  全表扫描
  
 如果多个字段 共同构成了这个索引 那么就存在 索引的创建顺序的问题
 
 a    b    c  三个列做了索引
 
 先按照a排序 如果a一样 那么按照b排序 如果b一样再按照c来进行排序 一旦其中某一个有序 那么其他的 就不用管了
 
 
 场景是这个表中有  a    b    c   d   e   f六个字段
 
 a是主键
 
 b  c  d三个列创建了索引
 
 
 select * from 表名   where  a=xxxx   走索引
 
 select b from 表名   where  b=xxx and c=xxx   and   d=xxxx 走索引
 
  select b from 表名   where  b=xxx 扫描二级索引树
  
  select b,c,d from 表名   where  b=xxx  扫描二级索引树
    
  select b,c,d from 表名   where  d=xxx 
  
  select * from 表名   where  c=xxx 二级索引
  
  select * from 表名   where  b=xxx  and c=xxxx 二级索引
  
  select * from 表名   where     c=xxxx and  b=xxx 进行 粗优化 条件就会跟上面一个一样顺序
 
   select * from 表名   where    b like  %小波波   走全表
   
     select * from 表名   where    b like  小波%波   走全表
     
       select * from 表名   where    b like  小波波%   索引

5、联合索引(覆盖索引)

不用回表

select a from 表名 where b=xxx
直接搜索二级索引树下的主键值  不用回表到主键一级索引树

explain select a from 表名 where b=xxx 可查看是否有索引下推

ere b like 小波波% 索引


### 5、联合索引(覆盖索引)

不用回表

select a from 表名 where b=xxx
直接搜索二级索引树下的主键值 不用回表到主键一级索引树




explain select a from 表名 where b=xxx 可查看是否有索引下推

你可能感兴趣的:(mysql,数据库,数据结构)