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会自己生成一个。

相关推荐
wrx繁星点点2 分钟前
事务的四大特性(ACID)
java·开发语言·数据库
小小娥子32 分钟前
Redis的基础认识与在ubuntu上的安装教程
java·数据库·redis·缓存
DieSnowK33 分钟前
[Redis][集群][下]详细讲解
数据库·redis·分布式·缓存·集群·高可用·新手向
计算机学姐1 小时前
基于SpringBoot+Vue的高校运动会管理系统
java·vue.js·spring boot·后端·mysql·intellij-idea·mybatis
-XWB-1 小时前
【MySQL】数据目录迁移
数据库·mysql
老华带你飞1 小时前
公寓管理系统|SprinBoot+vue夕阳红公寓管理系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·spring boot·课程设计
我明天再来学Web渗透1 小时前
【hot100-java】【二叉树的层序遍历】
java·开发语言·数据库·sql·算法·排序算法
Data 3172 小时前
Hive数仓操作(十一)
大数据·数据库·数据仓库·hive·hadoop
吱吱鼠叔2 小时前
MATLAB数据文件读写:2.矩阵数据读取
数据库·matlab·矩阵
掘根2 小时前
【MySQL】Ubuntu环境下MySQL的安装与卸载
数据库·mysql·centos