Mysql索引数据结构
索引
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,大小16k。 28位于16 - 24 之间,加载磁盘块3
- 加载磁盘块3,大小16k。 28位于25 - 31 之间,加载磁盘块8
- 加载磁盘块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)就会停止匹配。
假设有两个字段 name、age,为它们建立组合索引 (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 = ?
没有索引下推
先从存储引擎中拉取数据(根据name筛选的添加)
然后在mysql server(服务层) 根据age来进行数据筛选
有索引下推 能减少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索引数据结构相关推荐
- Mysql索引数据结构有多个选择,为什么一定要是B+树呢?_面试 (MySQL 索引为啥要选择 B+ 树)
Mysql索引数据结构 下面列举了常见的数据结构 二叉树 红黑树 Hash表 B-Tree(B树) Select * from t where t.col=5 我们在执行一条查询的Sql语句时候,在数 ...
- 【肝帝一周总结:全网最全最细】☀️Mysql 索引数据结构详解与索引优化☀️《❤️记得收藏❤️》
[肝帝一周总结:全网最全最细]☀️Mysql 索引数据结构详解与索引优化☀️<❤️记得收藏❤️> 目录
- MySQL索引数据结构二叉树、红黑树、B-Tree、B+Tree、Hash
索引:帮助MySQL高效获取数据的有序的数据结构. 假设我们有一张表table,包含Clo1和Clo2两个字段 内存地址 Clo1 Clo2 0x07 1 36 0x5A 2 20 0x7A 3 80 ...
- mysql索引数据结构图解_深入理解Mysql索引底层数据结构与算法
索引的定义:索引(Index)是帮助MySQL高效获取数据的数据结构. Q1:大家使用索引有没有想过这个问题?为什么索引能够帮助mysql高效获取数据?我一一给大家道来!在给大家讲之前,先更大家分享一 ...
- mysql id自动递增两个_浅析Mysql索引数据结构演变,让你一看就懂
前言 相信小伙伴应该都用到过mysql数据库,在mysql数据库中,为了提升查询效率,都会使用到索引技术.今天老顾就来介绍一下mysql索引的数据结构的演变. 数据查询 我们来看一下有个用户表,存放这 ...
- 一文说清MySQL索引数据结构
前言 接上篇说到,小A匆匆忙忙的赶回宿舍,因为晚上他要给女神整理讲解MySQL中索引数据结构资料.一边整理一边忍住不笑了起来,等小美看到这篇文章不得爱上自己.当上小美男朋友,从此踏上人生巅峰不是梦(该 ...
- MySQL事务、MySQL索引、MySQL索引数据结构详解
事务 DDL : 操作表,库 DCL : 授权 DML : 增删改数据 DQL : 查询 TCL : 数据库事务语言 #前期准备 CREATE TABLE account( #账户 id INT PR ...
- MySQL索引数据结构及算法原理
摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...
- MySQL索引数据结构详解
一.常见索引数据结构 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样.但是实现索引的方式却有很多种,所以这里也就引入了索引模型的概念.可以用于提高读写效率的数据结构很多,这里我先给你介绍三 ...
- 1万条数据大概占多大空间_Java互联网架构-性能优化Mysql索引数据结构详解
欢迎关注头条号:java小马哥 周一至周日下午三点半!精品技术文章准时送上!!! 精品学习资料获取通道,参见文末 一,索引数据结构红黑树,Hash,B+树详解 索引是帮助MySQL高效获取数据的排好序 ...
最新文章
- Mysql左连接分页查询
- 基于mysqld_multi实现MySQL 5.7.24多实例多进程配置
- eclipse 不能将maven jar包导入到tomcat中问题
- C# 之 日常问题积累(一)
- http实时推送技术
- Filenet公布第二批打包节点竞选名单
- 杰理AD14N/AD15N---Timer定时器问题
- java itex 打印pdf_【收藏】java使用ITEXT打印PDF
- 《印度合伙人》观影有感
- php解密encrypteddata,PHP解密支付宝小程序的加密数据、手机号的示例代码
- 深入浅出空间曲线的切线方程和法平面方程
- Sendmail和Openwebmail构建Linux下的Emai服务器
- linux安装谷歌中文,CentOS 7安装谷歌拼音中文输入法
- activated 使用
- 华为云服务器查看备份文件,云服务器备份文件
- 量子计算机与新南威尔士大学,新南威尔士大学声称量子计算的准确性
- java熔断器_详解spring cloud分布式关于熔断器
- json和gson傻傻分不清楚
- 六则糟糕代码的优化方案
- 抗疫得闲●流花湖(1)