mysql索引问题

今天在工作写项目的时候,突然发现很多地方没有加索引,然后我就去加了,查了不少资料,捡起来了不少东西,来简单聊一聊,工作中最重要的一个细节:索引

mysq的存储结构

首先要聊一聊mysql的存储模式,底层使用B+树存储,它和B-(B树,多叉树)区别就是,B+树的叶子节点是相连的(双向连表)

你们刚开始一定在想,为啥要怎么干,因为mysql只会在叶子结点存储数据,也就是说,路径上都只是拿来保存路径的,用来方便查询叶子结点。

所以用B-树查询太慢了,最快也是OlogN(它是一个N叉搜索树),B+树叶子结点可以左右查询,就不需要返回上一级,然后再查询另一叶子节点。

mysql索引结构:

上面既然说了是用的B+树作为mysql的存储结构,那么它的索引肯定也是使用B+树来存储的

索引的定义就是拿来加快查询的,如何加快,就得提到算法一个词语:

空间换时间

就像java中的使用Map存储一样,直接用key去查询value,思想是一样的。(HashMap底层也是树结构哦,小老弟!)

mysql中的索引

1、聚簇索引(主键)

它叶子结点就存放了主键值(很明显叶子节点是一个对象,类似有一个key和一个data,key存放的就是主键值),另一个区域存的除开主键后的所有数据。

2、辅助索引(普通索引,二级索引):

而辅助索引存放的是索引字段值,主键值。

索引的使用

3、回表

这里如果我们这样查询:

sql 复制代码
select age from user where name='小李'

由于我们用的是辅助索引,先查辅助索引树,发现只有name,没有age,所以这个时候就得去查主键索引树(回表),又要遍历一次主键索引树。

这里就能解答我的一个疑问:

为什么不直接一个字段一个索引,而是用组合索引(多个字段),字段太少就会回表查询,除非那种单独的使用,例如我就要通过name来查询,我就只能大度给name加一个索引,然后指定使用:

use index

sql 复制代码
select * from usera use index(nameindex) where user.name='小白'

所以使用select *就会回表查询,因为没有索引有全部字段。

4、最左前缀法则:

既然是用B+树,它的叶子节点就是一个从左往右的,所以创建索引的时候,也是按照指定的顺序的。

那么我们在使用索引时,也会从左往右查询,挨个挨个命中索引,

所以我们使用索引时,必须按照创建时的顺序,从左往右使用,但凡中间少了一个,就不会使用索引。顺序可以打乱,mysql会优化掉。

5、索引下推

没有使用索引下推

使用了索引下推:

很明显,就是提前判断了辅助索索引中有的字段,提前过滤掉,减少回表判断的次数。

来首打油诗:

全值匹配我最爱,最左前缀要遵守
带头大哥不能死,中间兄弟不能断
索引列上少计算,范围之后全失效
like百分写最右,覆盖索引不写星
不等空值还有or,索引失效要少用

mysql的两个数据库引擎 MYIASM和InnoDB

MYIASM的存储结构长这样:

也就是主键索引就是一个文件。另外一个是data文件。叶子结点对应数据在data文件里的地址。

而InnoDB是这样的:

叶子结点存放数据,所以呢,主键索引和数据是存放在一块的,所以它必须要有主键,没有指定mysql会自己生成一个。

相关推荐
IvorySQL6 小时前
PG 日报|新增 VACUUM 全维度统计信息补丁迭代
数据库·人工智能·postgresql·ivorysql
白露与泡影8 小时前
Redis 缓存实战:雪崩、穿透、击穿一次讲透
数据库·redis·缓存
赵渝强老师9 小时前
【赵渝强老师】使用Oracle可传输的表空间迁移数据
数据库·oracle
IpdataCloud10 小时前
跨区服玩家延迟高怎么办?用IP离线库自动分配到最近服务器
数据库·tcp/ip·github·php·ip
wuqingshun31415911 小时前
MYSQL默认的事务隔离级别是什么?为什么选择这个级别?
数据库·mysql
空中湖12 小时前
电池简史(五):极限之梦与终章——锂硫、锂空气、量子电池,以及你该知道的电池投资与生活指南
数据库·程序人生
蓝胖子酱13 小时前
在 Electron 中用 electron-store 实现加密存储与自定义格式文件
前端·javascript·数据库
snow@li14 小时前
Redis:数据库语法速查表 / 全景梳理
数据库·redis·缓存
Devlive 开源社区14 小时前
Nebula 1.6.0 发布:跨区域桶自动路由、秒传、文本/PDF 预览一次到位
数据库·sql
这个DBA有点耶14 小时前
导个数据中文全变问号?字符集这事儿真没那么简单
数据库·mysql·代码规范