目录
一、索引是什么
二、索引的数据结构
1.HASH
2.二叉搜索树
3.N叉树(B树)
4.B+树
5.B+树与B树的区别
三、MYSQL的页
1.页文件头与页文件尾
2.页主体
3.页目录
4.数据页头
四、B+在MYSQL索引中的应用
1.应用
2.计算三层树⾼的B+树可以存放多少条记录
五、索引分类
1.主键索引
2.普通索引
3.唯一索引
4.全文索引
5.聚集索引
6.非聚集索引(回表查询)
7.索引覆盖
六、索引的使用
1.自动创建
2.手动创建
2.1主键索引
1.创建表时创建主键
编辑编辑
2.创建表时单独指定主键列
3.修改表中的列为主键索引
2.2唯一索引
1.创建表时创建唯⼀键
2.创建表时单独指定唯⼀列
3.修改表中的列为唯⼀索引
2.3普通索引
1.创建时机
2..创建表时指定索引列
3.修改表中的列为普通索引
4.单独创建索引并指定索引名
3.查看索引
1.以行的形式去显示
2.show index
3.简要信息:desc 表名
4.删除索引
1.主键索引
1.1语法
1.2示例
2.其它索引
2.1语法
2.2示例
5.创建索引的注意事项
七、怎么查看自己写的SQL有没有走索引
1.查询所有
2.使用主键查询
3.子查询中使用索引
一、索引是什么
MySQL的索引是⼀种数据结构,它可以帮助数据库⾼效地查询、更新数据表中的数据。索引通过
⼀定的规则排列数据表中的记录,使得对表的查询可以通过对索引的搜索来加快速度
二、索引的数据结构
1.HASH
时间复杂度:O(1) 最重要的数据结构,没有之一 但不支持范围查找
2.二叉搜索树
中序遍历是一个有序的序列 --> 支持范围查询
时间复杂度:可能会退化成一个单边树O(n)
I/O的次数:数据库系统需要进行的读取或写入磁盘的总次数
3.N叉树(B树)
每个节点都可以超过两个节点,可以解决树的高度从而提高I/O的性能
时间复杂度:O(logn)
4.B+树
时间复杂度:O(logn)
可以有效控制树高
5.B+树与B树的区别
1.叶子节点之间有一个相互连接的引用,可以通过一个叶子节点找到与它相邻的兄弟节点
MYSQL在组织叶子节点的时候用的是双向链表
2.非叶子节点的值都包含在叶子节点中
MYSQL非叶子节点只保存了对叶子节点的引用,没保存真实的数据,所有真实的数据全都在叶子节点中保存
3.对于B+树而言,在相同的树高的情况下,查找任意元素的时间复杂度都一样,性能均衡
三、MYSQL的页
⻚是内存与磁盘交互的最⼩单元,默认⼤⼩为16KB
页的结构:文件头、文件尾、页主体
1.页文件头与页文件尾
2.页主体
⻚主体部分是保存真实数据的主要区域,每当创建⼀个新⻚,都会⾃动分配两个⾏,⼀个是⻚内最
⼩⾏ Infimun ,另⼀个是⻚内最⼤⾏ Supremun ,这两个⾏并不存储任何真实信息,⽽是做为数据⾏链表的头和尾,第⼀个数据⾏有⼀个记录下⼀⾏的地址偏移量的区域 next_record 将⻚内所有数据⾏组成了⼀个单向链表,此时新⻚的结构如下所⽰:
当向⼀个新⻚插⼊数据时,将 Infimun 连接第⼀个数据⾏,最后⼀⾏真实数据⾏连接Supremun ,这样数据⾏就构建成了⼀个单向链表,更多的⾏数据插⼊后,会按照主键从⼩到⼤的顺序进⾏链接,如下图所⽰
3.页目录
4.数据页头
数据⻚头记录了当前⻚保存数据相关的信息,如下图所⽰
四、B+在MYSQL索引中的应用
1.应用
⾮叶⼦节点保存索引数据,叶⼦节点保存真实数据,如下图所⽰
索引页,保存的是主键的值和子节点得到引用 叶子节点保存零点数据 数据页,一行的具体数据
页与页之间建立关联关系,最终形成一个双向循环链表
数据行的排序是按从做到右,从小到大的顺序去组织的,插入一行数据的时候会被安排到合适的位置
例:以查找id为5的记录,完整的检索过程如下
1. ⾸先判断B+树的根节点中的索引记录,此时 5 < 7 ,应访问左孩⼦节点,找到索引⻚2
2. 在索引⻚2中判断id的⼤⼩,找到与5相等的记录,命中,加载对应的数据⻚
以上的IO过程,加载索引⻚1 --> 加载索引⻚2 --> 加载数据⻚3
2.计算三层树⾼的B+树可以存放多少条记录
五、索引分类
1.主键索引
• 当在⼀个表上定义⼀个主键 PRIMARY KEY 时,InnoDB使⽤它作为聚集索引。
• 推荐为每个表定义⼀个主键。如果没有逻辑上唯⼀且⾮空的列或列集可以使⽤主键,则添加⼀个⾃增列。
如果为表定义了主键,则自动创建主键索引
如果没有为表定义主键索引,innodb会使用唯一列构建索引树 如果没有唯一列,则自动生成一个ROW_ID构建索引树
2.普通索引
• 最基本的索引类型,没有唯⼀性的限制。
• 可以为多列创建组合索引,称为复合索引或组全索引
为了提升查询效率,可以为查询频繁的列创建一个普通索引
如果手动创建了索引,都会生成一个与之对应的索引树(B+)(会占用磁盘空间)
索引中包含多个列,列在索引中的排序按创建时指定的顺序排序,同时每个索引行都会包含主键值
3.唯一索引
• 当在⼀个表上定义⼀个唯⼀键 UNQUE 时,⾃动创建唯⼀索引。
• 与普通索引类似,但区别在于唯⼀索引的列不允许有重复值。
4.全文索引
• 基于⽂本列(CHAR、VARCHAR或TEXT列)上创建,以加快对这些列中包含的数据查询和DML操作
• ⽤于全⽂搜索,仅MyISAM和InnoDB引擎⽀持。
有专门的文档数据库,可以高效的处理文档搜索
5.聚集索引
• 与主键索引是同义词
• 如果没有为表定义 PRIMARY KEY, InnoDB使⽤第⼀个 UNIQUE 和 NOT NULL 的列作为聚集索
引。
• 如果表中没有 PRIMARY KEY 或合适的 UNIQUE 索引,InnoDB会为新插⼊的⾏⽣成⼀个⾏号并
⽤6字节的 ROW_ID 字段记录, ROW_ID 单调递增,并使⽤ ROW_ID 做为索引。
6.非聚集索引(回表查询)
• 聚集索引以外的索引称为⾮聚集索引或⼆级索引
• ⼆级索引中的每条记录都包含该⾏的主键列,以及⼆级索引指定的列。
• InnoDB使⽤这个主键值来搜索聚集索引中的⾏,这个过程称为回表查询
通过普通索引的列为条件查到主键值,再用主键值去主键索引树中去查找学生的详细信息,涉及到两个索引树,这个过程叫回表查询
7.索引覆盖
• 当⼀个select语句使⽤了普通索引且查询列表中的列刚好是创建普通索引时的所有或部分列,这时就可以直接返回数据,⽽不⽤回表查询,这样的现象称为索引覆盖
查询的列包含在创建的索引的列中,就可以直接从普通索引中返回结果,这个现象叫索引覆盖
六、索引的使用
1.自动创建
• 当我们为⼀张表加主键约束(Primary key),外键约束(Foreign Key),唯⼀约束(Unique)时,
MySQL会为对应的的列⾃动创建⼀个索引
• 如果表不指定任何约束时,MySQL会⾃动为每⼀列⽣成⼀个索引并⽤ ROW_ID 进⾏标识
2.手动创建
2.1主键索引
1.创建表时创建主键
2.创建表时单独指定主键列
3.修改表中的列为主键索引
2.2唯一索引
1.创建表时创建唯⼀键
2.创建表时单独指定唯⼀列
3.修改表中的列为唯⼀索引
2.3普通索引
1.创建时机
1.创建表的时候,明确知道某些列是频繁查询的列,就直接创建(当表中数据比较少时,全表扫描的效率可能比使用索引的效率还要高)
2.随着业务不断地发展,在版本迭代的过程中添加索引
2..创建表时指定索引列
一个复合索引,索引中包含两个列
3.修改表中的列为普通索引
4.单独创建索引并指定索引名
create index : 创建索引的关键字 idx_index3_sno : 为索引命名(idx_表名_索引包含的列名)
推荐以后使用这种方式创建索引:create index idx_index5_sno_classId on index5(sno, class_id);
3.查看索引
1.以行的形式去显示
2.show index
3.简要信息:desc 表名
4.删除索引
1.主键索引
1.1语法
alter table 表名 drop primary key;
删除主键时不指定索引名,因为表中只有一个主键 删除之前要把自增取消
如果存在自增列,则会报错
1.2示例
2.其它索引
2.1语法
alter table 表名 drop index 索引名;
2.2示例
5.创建索引的注意事项
• 索引应该创建在⾼频查询的列上
• 索引需要占⽤额外的存储空间
• 对表进⾏插⼊、更新和删除操作时,同时也会修索引,可能会影响性能
• 创建过多或不合理的索引会导致性能下降,需要谨慎选择和规划索引
七、怎么查看自己写的SQL有没有走索引
可以查看执行计划 explain select...
1.查询所有
2.使用主键查询
3.子查询中使用索引
为name建立索引