风也温柔

计算机科学知识库

数据库索引 数据结构 MySQL 索引

  索引

  文章目录

  索引概述

  如下图

  [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img--44)(索引{MRDEP$KS]9N[@0O5.png)]

  使用

   sele * from user where age=45;

  如果不使用索引,将会进行全表扫描

  若使用索引

  V

  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数据库,将索引的具体类型主要分为以下几类:主键索引、唯一索引、常规索引、全文索引。

  分类含义特点关键字

  主键索引

  针对于表中主键创建的索引

  默认自动创建, 只能 有一个

  唯一索引

  避免同一个表中某数据列中的值重复

  可以有多个

  常规索引

  快速定位特定数据

  可以有多个

  全文索引

  全文索引查找的是文本中的关键词,而不是比 较索引中的值

  可以有多个

  聚集索引和二级索引如下

  C

  注:

  查找过程:

  使用语句:

   select * from user where name='Arm';

  E

  寻找 因为根据 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='软件工程';

  DE8

  可以看到 查询走的 联合索引 ,这是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';

  运行结果:

  DE9

  Extra含义

  Using where; Using Index

  查找使用了索引数据库索引 数据结构 MySQL 索引,但是需要的数据都在索引列中能找到,所以不需 要回表查询数据

  Using index

  查找使用了索引,但是需要回表查询数据

  解释:

  语句1 和语句2 直接可以走 联合索引 找到, 查询一次

  但是语句3 ,多了一个 name字段,联合索引走完后找到 id,再回表查询通过 id 找到 name, 查询两次

  语句4 直接通过 id 寻找,走聚集索引,查询一次

  如下图

  IND

  由此可见,语句1 和 语句2 效率高于 语句3 和 语句4,因为后两句要回表查询。

  结论:要避免使用 *,因为很容易出现回表查询

  前缀索引

  当字段类型为字符串(,text等)时,有时候需要索引很长的字符串,这会让 索引变得很大,查询时,浪费大量的磁盘IO, 影响查询效率。此时可以只将字符串的一部分前缀,建 立索引,这样可以大大节约索引空间,从而提高索引效率。

  单列索引与联合索引

  单列索引:即一个索引只包含单个列。

  联合索引:即一个索引包含了多个列。

  示例:

  INDE

  如上图,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