索引

Hash Mysql使用的数据结构

优点

根据HashCode计算得到存储位置的下标,速度快,时间复杂度O(1)

缺点

  • Hash结构会造成Hash碰撞,HashMap通过高16位异或低16位减少Hash冲突。
  • 利用Hash存储的话需要将所有的数据文件添加到内存中,比较耗费内存。
  • Hash等值查询效率快,但不支持范围查询,需要从前往后扫描一遍,时间复杂度O(n)

二叉树与红黑树

缺点

  • 每个节点存放一个数据。而内存从磁盘取回一个大小为4k的整数倍的大小的块,Mysql默认读取16k的大小
  • 节点一多,树的深度变深,io次数会跟随深度变多,影响数据读取的效率。

B树

优点

  • 每个节点能存放多个数据,既符合能存放一块的数据,Mysql中可每个节点能存放16K的数据块
  • 寻找某个元素加载的磁盘块比较少。既IO次数少

寻找28

  1. 加载磁盘块1,大小16k。 28位于16 - 24 之间,加载磁盘块3
  2. 加载磁盘块3,大小16k。 28位于25 - 31 之间,加载磁盘块8
  3. 加载磁盘块8,大小16k。 28存在于磁盘块8。总加载大小为48k

缺点

  • 实际数据占用过大会导致每一层存储的有效数据过少。
  • 不支持兄弟磁盘块之间的读取

假设一个数据大小1k(忽略其他元素),既一个磁盘块能存储16个数据

三层的结构存储 16 * 16 * 16 = 4096。数据量过少

B+树 Mysql使用的数据结构

优点

  • 主键值出现在多个层次中,作为条件筛选。
  • 非叶子节点不存储实际数据。
  • 兄弟叶子节点使用指针相连接
  • 支持主键的范围查找与分页查找。支持叶子节点的随机查找

非叶子节点不存储实际数据,假设每个指针大小10b,既一个磁盘块16k能存储1600个指针

三层的结构存储 1600 * 1600 * 16= 40960000。超过千万数据

Mysql存储引擎

Mysql中有两类索引数据结构:Hash 与 B+树

其中 InnoDB、MyISAM两种存储引擎使用B+树作为索引数据结构

Memory存储引擎使用Hash作为索引数据结构。 InnoDB也可以用Hash索引(InnoDB使用自适应Hash,由Mysql处理,用户无法干预)

InnoDB 聚族索引(索引与数据存放一起)

文件存放格式

xxx.frm      // 存储数据结构
xxx.idb     // 存储实际数据文件  innoDB将索引与数据一起存储

B+树数据存储结构

使用InnoDB作为存储引擎,B+树叶子节点实际数据存放:主键+表中其他字段数据(实际的整行数据)

如果没有主键则使用唯一键,没有唯一键会生成6字节的row_id作为主键

如果以其他字段创建索引,则会再生成一棵B+树,叶子节点存放***主键ID***

MyISAM 非聚族索引(索引不与数据存放一起)

文件存放格式

xxx.frm      // 存储数据结构
xxx.MYD     // MyISAM Data 存储实际数据
xxx.MYI     // MyISAM Index 存储索引

B+树数据存储结构

使用InnoDB作为存储引擎,B+树叶子节点实际数据存放:该数据在表中的地址(实际数据的存放的地址),然后通过地址去访问数据

Mysql名词

回表

回表

先通过普通索引的值定位聚簇索引值,再通过聚簇索引的值定位行记录数据,需要扫描两次索引B+树,它的性能较扫一遍索引树更低。

索引覆盖

索引覆盖

只需要在一棵索引树上就能获取SQL所需的所有列数据,无需回表,速度更快。

最左匹配

最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。

假设有两个字段 nameage,为它们建立组合索引 (name,age)

where name = ? and age = ?      符合最左匹配原则
where name = ?                 符合最左匹配原则
where age = ?                  不符合最左匹配原则,age前方需要先经过name
where age = ? and name = ?         通过mysql优化器调整为where name = ? and age = ?  符合最左匹配原则

索引下推

索引下推

索引下推的唯一缺点是需要在磁盘上多做数据筛选,由原来放到在内存中筛选(mysql server),现在放到磁盘中筛选。

不过因为索引下推到磁盘筛选后,实际上返回的数据量更加,整理IO量大大减少,反而提升了性能

select * from table where where name = ? and age = ?
  1. 没有索引下推

    先从存储引擎中拉取数据(根据name筛选的添加)

    然后在mysql server(服务层) 根据age来进行数据筛选

  2. 有索引下推 能减少IO量

    直接使用(name,age)从存储引擎中拉取数据

    无需通过在mysql server(服务层) 筛选

索引匹配

  • 全值匹配

    全值匹配指的是和索引中的所有列进行匹配

    (name,age,pos)组合索引
    select * from staffs where name = 'Lin' and age = 23 and pos = 'dev';
    
  • 匹配最左前缀

    只匹配前面的几列

    (name,age,pos)组合索引
    select * from staffs where name = 'Lin' and age = 23;
    select * from staffs where name = 'Lin;
    
  • 匹配列前缀

    可以匹配某一列的值的开头部分

    (name,age,pos)组合索引
    select * from staffs where name like 'L%';    索引有效
    select * from staffs where name like '%L';    索引失效
    
  • 匹配范围值

    可以查找某一个范围的数据

    (name,age,pos)组合索引
    select * from staffs where name > 'Lin';   索引有效。  > < 后面的索引失效
    
  • 精确匹配某一列并范围匹配另一列

    可以查询第一列的全部和第二列的部分

    (name,age,pos)组合索引
    select * from staffs where name = 'Lin' and age > 23;   索引有效。  > < 后面的索引失效
    
  • 只访问索引的查询

    查询的时候只需要访问索引,不需要访问数据行,本质上就是覆盖索引

    (name,age,pos)组合索引
    select * from staffs where name = 'Lin' and age = 23 and pos = 'dev';
    select * from staffs where pos = 'dev' and name = 'Lin' and age = 23 ;  通过mysql优化器 优化为上一条sql 索引有效
    

索引失效

  • like左%

    name字段创建索引

    select name from name like 'J%'  索引有效
    select name from name like '%J'  索引失效
    
  • > < 后面索引失效

    (name,age,pos)为组合索引

    select name from name > 'Lin' 索引有效 本身就是有序排列
    select name from name = 'Lin' and age > 20 and pos = 20  pos不走索引,该sql只走(name,age),pos因前面使用>造成后续索引失效
    
  • or 字段索引失效

    总结:

    单列索引中 or 会使用索引。

    组合索引中:1、全部列都是组合索引,or走索引。属于特殊情况。 2、部分是组合索引,or失效,直接全表查询

    表abc中 字段(a、b、c) 组合索引(abc)

    表abc2中 字段(a、b、c、d) 组合索引(abc)

    表actor中 字段 actor_name 是索引列

    or走索引 因为表abc三个字段abc全部被组合索引覆盖,无论什么情况都能通过abc索引获取。属于特殊情况
    select * from abc where a = 1 or b = 2;   or不走索引, 表abc2中abcd四个字段没被全部覆盖。需要or直接全表查询,开发中建议使用in 或 union all 替换 or
    select * from abc2 where a=1 or b = 2;or走索引 因为actor_name是一个单列索引 能通过b+树搜索
    select * from actor where actor_name = 'Lin' or actor_name  = 'Chen'
    
  • 隐式类型转换会造成索引失效

phone列 varchar类型
select * from user where phone = 13000001234; 索引失效
select * from user where phone = ‘13000001234’; 索引有效


# 索引优化细节1. 当使用索引进行查询的时候尽量不用使用表达式,把计算放到业务层而不是数据库层2. 尽量使用主键查询,而不是使用其他索引,因为主键查询不会触发回表查询3. 使用前缀索引4. 使用索引扫描排序5. union all,in,or都能使用索引,但是推荐使用in表actor中     字段 actor_name 是索引列。```union allselect * from actor where actor_id = 1 union all select * from actor where actor_id = 2;inselect * from actor where actor_id in (1,2);or  select * from actor where actor_id = 1 or actor_id = 2;```6. 范围列可以使用索引范围条件是:`<`、`<=`、` >=、`>`、`between`。范围查询可以使用到索引,但是范围列后面的列无法用到索引,索引最多用于一个范围列。7. 强制转换类型会转换为全表扫描```phone列 varchar类型select * from user where phone = 13000001234;         索引失效select * from user where phone = '13000001234';          索引有效```8. 更新十分频繁,数据区分不高的字段不宜建立索引1. 更新会变更b+树,更新频繁的字段建立索引会大大降级数据库性能2. 类似与这类区分度不大的属性,建立索引没有意义,不能有效的过滤数据3. 一般区分度在80%以上的时候可以建立索引,区分度可用以下sql计算```count(distinct(列名)) / count(*)```9. 创建索引的列,不允许为null,可能会得到不符合预期的结果10. 当需要进行表练级的时候,最好不要超过三张表,因为需要join的字段,数据类型必须一致11. 能使用limit的时候尽量使用limit12. 单表索引建议控制在5个以内13. 单索引字段数不允许超过5个(组合索引)14. 创建索引的时候应该避免以下概念1. 索引越多越好2. 过早优化,在不了解系统的情况下优化

Mysql索引数据结构相关推荐

  1. Mysql索引数据结构有多个选择,为什么一定要是B+树呢?_面试 (MySQL 索引为啥要选择 B+ 树)

    Mysql索引数据结构 下面列举了常见的数据结构 二叉树 红黑树 Hash表 B-Tree(B树) Select * from t where t.col=5 我们在执行一条查询的Sql语句时候,在数 ...

  2. 【肝帝一周总结:全网最全最细】☀️Mysql 索引数据结构详解与索引优化☀️《❤️记得收藏❤️》

    [肝帝一周总结:全网最全最细]☀️Mysql 索引数据结构详解与索引优化☀️<❤️记得收藏❤️> 目录

  3. MySQL索引数据结构二叉树、红黑树、B-Tree、B+Tree、Hash

    索引:帮助MySQL高效获取数据的有序的数据结构. 假设我们有一张表table,包含Clo1和Clo2两个字段 内存地址 Clo1 Clo2 0x07 1 36 0x5A 2 20 0x7A 3 80 ...

  4. mysql索引数据结构图解_深入理解Mysql索引底层数据结构与算法

    索引的定义:索引(Index)是帮助MySQL高效获取数据的数据结构. Q1:大家使用索引有没有想过这个问题?为什么索引能够帮助mysql高效获取数据?我一一给大家道来!在给大家讲之前,先更大家分享一 ...

  5. mysql id自动递增两个_浅析Mysql索引数据结构演变,让你一看就懂

    前言 相信小伙伴应该都用到过mysql数据库,在mysql数据库中,为了提升查询效率,都会使用到索引技术.今天老顾就来介绍一下mysql索引的数据结构的演变. 数据查询 我们来看一下有个用户表,存放这 ...

  6. 一文说清MySQL索引数据结构

    前言 接上篇说到,小A匆匆忙忙的赶回宿舍,因为晚上他要给女神整理讲解MySQL中索引数据结构资料.一边整理一边忍住不笑了起来,等小美看到这篇文章不得爱上自己.当上小美男朋友,从此踏上人生巅峰不是梦(该 ...

  7. MySQL事务、MySQL索引、MySQL索引数据结构详解

    事务 DDL : 操作表,库 DCL : 授权 DML : 增删改数据 DQL : 查询 TCL : 数据库事务语言 #前期准备 CREATE TABLE account( #账户 id INT PR ...

  8. MySQL索引数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  9. MySQL索引数据结构详解

    一.常见索引数据结构 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样.但是实现索引的方式却有很多种,所以这里也就引入了索引模型的概念.可以用于提高读写效率的数据结构很多,这里我先给你介绍三 ...

  10. 1万条数据大概占多大空间_Java互联网架构-性能优化Mysql索引数据结构详解

    欢迎关注头条号:java小马哥 周一至周日下午三点半!精品技术文章准时送上!!! 精品学习资料获取通道,参见文末 一,索引数据结构红黑树,Hash,B+树详解 索引是帮助MySQL高效获取数据的排好序 ...

最新文章

  1. Mysql左连接分页查询
  2. 基于mysqld_multi实现MySQL 5.7.24多实例多进程配置
  3. eclipse 不能将maven jar包导入到tomcat中问题
  4. C# 之 日常问题积累(一)
  5. http实时推送技术
  6. Filenet公布第二批打包节点竞选名单
  7. 杰理AD14N/AD15N---Timer定时器问题
  8. java itex 打印pdf_【收藏】java使用ITEXT打印PDF
  9. 《印度合伙人》观影有感
  10. php解密encrypteddata,PHP解密支付宝小程序的加密数据、手机号的示例代码
  11. 深入浅出空间曲线的切线方程和法平面方程
  12. Sendmail和Openwebmail构建Linux下的Emai服务器
  13. linux安装谷歌中文,CentOS 7安装谷歌拼音中文输入法
  14. activated 使用
  15. 华为云服务器查看备份文件,云服务器备份文件
  16. 量子计算机与新南威尔士大学,新南威尔士大学声称量子计算的准确性
  17. java熔断器_详解spring cloud分布式关于熔断器
  18. json和gson傻傻分不清楚
  19. 六则糟糕代码的优化方案
  20. 抗疫得闲●流花湖(1)

热门文章

  1. SVN的重启Apache2的重启
  2. linux驱动笔记1---linux内核驱动目录结构
  3. 唧唧歪歪 | 什么东西可以不用,但是一定得有?
  4. 如何摆姿势才能拍出效果不错的个人商务照片
  5. mysql新增字段顺序_mysql 添加字段、删除字段、调整字段顺序 转
  6. stc8a8k64s4单片机控制步进电机(四相八拍)实现顺时针转一圈和逆时针转一圈
  7. python实现滑动验证码_使用python实现滑动验证码
  8. 啥是物联网?一个西瓜告诉你!
  9. ECharts的学习(二):制作一个简单的饼状图,并对其设置样式
  10. AIDL for HALs实战