文章目录
索引概述
如下图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img--44)(索引{MRDEP$KS]9N[@0O5.png)]
使用
sele * from user where age=45;
如果不使用索引,将会进行全表扫描
若使用索引
45>36走右子树,45小于48走左子树,只需要查询三次,效率提升
缺点
索引结构 B+Tree
B+Tree是B-Tree的变种,我们以一颗最大度数(max-)为4(4阶)的b+tree为例,来看一 下其结构示意图:
B+Tree 与 B-Tree相比,主要有以下三点区别:
Hash
哈希索引就是采用一定的hash算法,将键值换算成新的hash值,映射到对应的槽位上,然后存储在 hash表中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img--47)(索引hash.png)]
其中 name 经过hash算法映射到槽位,b4a96就是常遇春的hash值
如果两个键值映射到了同一个槽位,也就是hash冲突(hash碰撞),可以通过链表解决【如 金庸与杨逍】
特点
为什么存储引擎选择使用B+tree索引结构?
索引分类
在MySQL数据库,将索引的具体类型主要分为以下几类:主键索引、唯一索引、常规索引、全文索引。
分类含义特点关键字
主键索引
针对于表中主键创建的索引
默认自动创建, 只能 有一个
唯一索引
避免同一个表中某数据列中的值重复
可以有多个
常规索引
快速定位特定数据
可以有多个
全文索引
全文索引查找的是文本中的关键词,而不是比 较索引中的值
可以有多个
聚集索引和二级索引如下
注:
查找过程:
使用语句:
select * from user where name='Arm';
寻找 因为根据 name字段寻找Arm,所以到二级索引,因为 A 在 L 前,所以到左子树,A 在 G 之前定位到 Arm 查到主键值 10。因为返回数据是 *,回到 聚集索引 找到 10,最终找到 10 对应的行。
以上过程称为回表查询
由上可知,使用 id 比 使用 name 查询速度更快
回表查询:
这种先到二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,获取数据的方式,就称之为回表查询。
索引语法 SQL性能分析 索引使用 SQL提示
示例:
假设有 联合索引 和 单列索引
-- 为 profession创建单列索引
create index idx_user_pro on tb_user(profession);
-- 展示执行计划
explain select * from tb_user where profession='软件工程';
可以看到 查询走的 联合索引 ,这是MySQL自动选择的结果。
如果我们要指定使用哪个索引可以吗? 此时就可以借助于 MySQL的SQL提示来完成。
SQL提示:是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优 化操作的目的。
explain select * from tb_user use index(idx_user_pro) where profession = '软件工程';
覆盖索引
覆盖索引是指 查询使用了索引,并 且需要返回的列数据库索引 数据结构,在该索引中已经全部能够找到
注:尽量使用覆盖索引,减少 *
-- 1
explain select id, profession from tb_user where profession = '软件工程' and age =31 and status = '0' ;
-- 2
explain select id,profession,age, status from tb_user where profession = '软件工程' and age = 31 and status = '0' ;
-- 3
explain select id,profession,age, status, name from tb_user where profession = '软件工程' and age = 31 and status = '0' ;
-- 4
explain select * from tb_user where profession = '软件工程' and age = 31 and status= '0';
运行结果:
Extra含义
Using where; Using Index
查找使用了索引数据库索引 数据结构 MySQL 索引,但是需要的数据都在索引列中能找到,所以不需 要回表查询数据
Using index
查找使用了索引,但是需要回表查询数据
解释:
语句1 和语句2 直接可以走 联合索引 找到, 查询一次
但是语句3 ,多了一个 name字段,联合索引走完后找到 id,再回表查询通过 id 找到 name, 查询两次
语句4 直接通过 id 寻找,走聚集索引,查询一次
如下图
由此可见,语句1 和 语句2 效率高于 语句3 和 语句4,因为后两句要回表查询。
结论:要避免使用 *,因为很容易出现回表查询
前缀索引
当字段类型为字符串(,text等)时,有时候需要索引很长的字符串,这会让 索引变得很大,查询时,浪费大量的磁盘IO, 影响查询效率。此时可以只将字符串的一部分前缀,建 立索引,这样可以大大节约索引空间,从而提高索引效率。
单列索引与联合索引
单列索引:即一个索引只包含单个列。
联合索引:即一个索引包含了多个列。
示例:
如上图,phone和name都为单列索引
使用一下语句
explain select id,name,phone from tb_user where name='韩信' and phone='17799990010';
由图可见,可以看到这样查询需要回表查询,(MySQL 会在两个索引中自动选择更高效索引进行匹配)
当我们建立联合索引
create unique index idx_user_phone_name on tb_user(phone,name);
此时,查询时,就走了联合索引,而在联合索引中包含 phone、name的信息,在叶子节点下挂的是对 应的主键id数据库索引 数据结构,所以查询是无需回表查询的
对应以上,情况如下
注1: index on (phone,name);此语句中(phone,name)的phone和name,颠倒这两个字段的顺序是不一样的(最左前缀法),所以在选择顺序时,需要斟酌。
注2:如果存在多个查询条件,考虑针对于查询字段建立索引时,建议建立联合索引, 而非单列索引。
文章来源:https://blog.csdn.net/qq_48778364/article/details/126532964