MySQL之索引原理

二分查找法
B+Tree
索引分析与优化

索引分类

索引可以提升查询速度,会影响where查询,以及order by排序。

  • 从索引存储结构划分:
    • B Tree索引、Hash索引、FULLTEXT全文索引、R Tree索引
  • 从应用层次划分:
    • 普通索引、唯一索引、主键索引、复合索引
  • 从索引键值类型划分:
    • 主键索引、辅助索引(二级索引)
  • 从数据存储和索引键值逻辑关系划分:
    • 聚集索引(聚簇索引)、非聚集索引(非聚簇索引)

  • 普通索引:
    • 创建方法:
      • 创建索引:create index 索引的名字 on 表名 (字段名);
      • 修改表时创建索引:alter table 表名 add index 索引的名字(字段名);
      • 创建表时创建索引:create table 表名 ([…],index 索引名字(字段名);
      • 查看索引命令:show index from 表名;
      • 删除索引命令:drop index 索引名字 on 表名;
  • 唯一索引:
    • 与普通索引类似,但是索引字段的值必须唯一,但允许有空值。再创建或修改表时追加唯一索引,就会自动创建对应的唯一索引。
    • 创建方法:
      • create unique index 索引的名字 on 表名 (字段名);
      • alter table 表名 add unique index 索引的名字(字段名);
      • create table 表名 ([…],unique 索引的名字(字段名);
  • 主键索引
    • 特殊的唯一索引,不允许有空值。
    • 创建方法:
      • create table 表名 ([…],primary key(字段名));
      • alter table 表名 add primary key(字段名);
  • 复合索引
    • 可以在多个列上建立索引,也叫组合索引。复合索引在数据库操作期间所需的开销更小,可以代替多个单一索引。
    • 复合索引还有两个概念,一是窄索引,二是宽索引。窄索引指的是索引列为1-2列,宽索引为列超过2列,设计复合索引的重要原则是能用窄索引就不要用宽索引,因为窄索引比宽索引开销低,效率高。
    • 创建方法:
      • create index 索引名字 on 表名(字段1,字段2…);
      • alter table 表名 add index 索引名字 (字段1,字段2…);
      • create talbe 表名 ([…]index 索引名字(字段1,字段2…);
    • 使用复合索引时的注意事项:
      • 复合索引字段是有顺序的,在查询使用时按照索引字段的顺序使用。如果顺序不一致,索引不会生效。比如,创建索引是顺序 (name,age) ,使用索引时 (age,name) ,此时索引不会生效。
      • 何时使用复合索引,要根据where条件建立索引,注意不要过多使用索引,过多使用会对更新操作效率有很大影响。
      • 如果表已经建立了 (name,age) 索引,就没有必要单独建立 (name) 索引了;如果现在已经有了 (name) 索引,如果查询需要 (name,age) 索引,可以建立 (name,age) 复合索引,对于查询有一定提高,如果建立了 (name,age) 索引,此时 (name) 可以去掉,如果有一个宽索引不如拆分为几个窄索引。
  • 全文索引:
    • 查询操作在数据量较少时,可以使用like进行模糊查询,但是对于大量的文本数据检索,效率很低,此时使用全文索引,查询速度会比like快很多倍。在MySQL5.6版本以前,全文索引只支持MyISAM引擎,从MySQL5.6开始也支持了InnoDB引擎。
    • 创建方法:
      • create fulltext index 索引名字 on 表名 (字段名);
      • alter table 表名 add fulltext 索引名字(字段名);
      • create table 表名 ([…],fulltext key 索引名字(字段名));
    • sql语句和like不同:
      • select * from 表名 where match(字段名) against(‘匹配内容’);
      • 全文索引必须在字符串、文本字段上建立
      • 全文索引字段值必须在最大字符最小字符之间的才会有效。(innodb :3-84;myisam:4-84)
      • 全文索引字段值要进行切词处理,按 syntax 字符进行切割,比如“我是关羽 啊”,根据空格切割为“我是关羽”和“啊”
      • 全文索引匹配查询,默认是用的是等值匹配,比如“我是关羽”,只会查到“我是关羽”,不会查到“我是关羽羽”,如果需要可以用boolen模式查询“我是关羽*”。更多查询规则可以查看命令:show variables like ‘%ft%’;

索引原理

MySQL官方对索引的定义:
Indexes are used to find rows with specific column values quickly. Without an index, MySQL must begin with the first row and then read through the entire table to find the relevant rows. The larger the table, the more this costs. If the table has an index for the columns in question, MySQL can quickly determine the position to seek to in the middle of the data file without having to look at all the data. This is much faster than reading every row sequentially.

翻译过来:
索引用于快速查找具有特定列值的行。如果没有索引,MySQL 必须从第一行开始,然后读取整个表以查找相关行。桌子越大,成本越高。如果表有相关列的索引,MySQL 可以快速确定要在数据文件中间查找的位置,而无需查看所有数据。这比顺序读取每一行要快得多。

  • 索引是物理数据页存储,在数据文件中(InnoDB,idb文件),利用数据页(page)存储。
  • 索引可以加快检索速度,但是同时也会降低增删改的操作速度,索引维护需要代价。

  • 二分查找法:

    • 二分查找法也叫做折半查找法,它是在有序数组中查找指定数据的搜索算法。它的优点是:等值查询、范围查询性能优秀,缺点是:新增、更新、删除数据维护成本高。
      • 二分查找步骤:
        • 定位low和high两个指针位置

        • 计算(low+Right)/ 2

        • 结果向下取整后,指针位置的值与查找值大小比较

        • 指针位置值大于目标值指针位置就-1;如果小于目标值指针位置就+1

          • 图示:在这里插入图片描述

  • B+Tree结构:

    • 非叶子节点不存储data数据,只存储索引值,使得能够存储更多的索引值
    • 叶子结点包含了所有的索引值和data数据
    • 叶子结点用指针连接,提高区间的访问速度,不必进行回旋查找
      • 和B树相比,B+树进行范围查找时,只需要查找定位两个节点的索引值,然后利用叶子结点的指针进行遍历即可。

        • 图示:
          在这里插入图片描述

  • 索引分析与优化

    • EXPLAIN
      在这里插入图片描述
      • select_type:表示查询的类型,常用值如下:
        • SIMPLE:表示查询的语句不包含子查询或UNION(最常见的查询类型
        • PRIMARY:表示此查询是最外层的查询
        • UNION:表示此查询是UNION的第二个或后续的查询
        • DEPENDENT UNION:UNION中的第二个或后续的查询语句,使用了外面的查询结果
        • UNION RESULT:UNION的结果
        • SUBQUERY:SELECT子查询语句
        • DEPENDENT SUBQUERY:SELECT子查询语句依赖外层查询的结果
      • type:表示存储引擎查询数据时采用的方式。通过它可以判断出查询的是全表扫描还是基于索引的部分扫描。常用值如下:效率依次增强
        • ALL:表示全表扫描,性能最差。
        • index:表示基于索引的全表扫描,先扫描索引再扫描全表数据。-> 基于排序的情况下,效率会比 ALL 高
        • range:表示使用索引范围查询,如:>、>=、<、<=、in 等
        • ref:表示使用非唯一索引进行单值查询,即普通索引
        • eq_ref:一般情况下出现在多表join查询,表示前面的表的每一个记录,都只能匹配后面表的一行结果
        • const:表示使用主键或唯一索引做等值查询->常量查询
        • NULL:表示不用访问表,速度最快
      • possible_keys:表示查询时能够使用到的索引,并不是真正使用
      • key:表示查询时真正使用的索引,显示的是索引名称
      • rows:表示MySQL查询优化器会根据统计信息,估算sql查询到结果需要扫描多少行记录。原则上是rows越少越好,直观反映了sql效率的高低
      • key_len:表示查询使用了索引的字节数量,可以判断是全部使用了组合索引,或只用到索引的最左部分的部分字段值
        • key_len 的计算规则如下:

        • 字符串类型:
          字符串长度跟字符集有关:latin1=1、gbk=2、utf8=3、utf8mb4=4
          char(n): n * 字符集长度

          varchar(n):n * 字符集长度+2字节

        • 数值类型:
          TINYINT=1、SMALLINT=2、MEDIUMINT=3、INT和FLOAT=4、BIGINT和DOUBLE=8

        • 时间类型:
          DATE:3、TIMESTAMP=4、DATETIME=8

        • 字段属性:
          NULL属性占用1个字节,如果一个字段设置了NOT NULL,则没有此项

      • Extra:表示很多额外的信息,各种操作会在Extra提示相关信息,常见几种如下:
        • Using where
          表示查询需要通过索引回表查询数据。
        • Using index
          表示查询需要通过索引,索引就可以满足所需数据。
        • Using filesort
          表示查询出来的结果需要额外排序,数据量小在内存,大的话在磁盘,因此有Using filesort建议优化,对CPU消耗较大
        • Using temprorary
          表示查询使用到了临时表空间,一般出现于去重、分组等操作

  • 回表查询
    • 通过索引查询主键值,然后再去聚合索引查询记录信息

  • 覆盖索引
    • 只需要在一棵索引树上就能获取sql所需的所有数据,无需回表,速度更快。

  • 最左前缀原则

    • 复合索引使用时遵循最左前缀原则,即最左优先,比如 name和gender 为组合索引,那么查询中使用到了最左边的name就会使用索引,如果仅使用了第二个,那么索引就会失效。如图↓↓↓↓↓

    在这里插入图片描述

    在这里插入图片描述

    • 图1:查询所有数据
    • 图2:查询现在索引
    • 图3:创建符合索引 name——gender
    • 图4:遵循了最左前缀原则
    • 图5:未遵循最左前缀原则
    • 图6:遵循了最左前缀原则
    • 图7:遵循了最左前缀原则,MySQL优化器进行了优化,即对条件顺序进行了优化

  • LIKE查询
    • %写在后面会起作用(最佳左前缀法则)
      select * from employee where name ‘关羽%’;
      通过 show variables like ‘%optimizer_switch%’; 查看,index_condition_pushdown=on,简称ICP,表示开启,索引条件过滤下沉到存储引擎层。

  • NULL查询
    • 对MySQL来讲,NULL是特殊的值。比如:不能使用=,<,>这样的运算符,对NULL做算数运算的结果都为NULL,count是不会计算值为NULL的行。

其他章节 -> 跳转

end...
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: MySQL索引是一种特殊的数据结构,用于快速查找数据表中的行。它可以帮助 MySQL 在处理 SELECT、UPDATE 和 DELETE 语句时更快地找到所需的数据。 索引的工作方式类似于书籍的目录。例如,如果你想在一本书中查找有关“计算机科学”的信息,你可以在书的目录中找到“计算机科学”这一项,然后转到相应的页码来查看内容。同样,在 MySQL 中,你可以在索引中查找特定的值,然后转到相应的数据行来查看内容。 MySQL 支持多种索引类型,包括普通索引、唯一索引、主键索引全文索引。普通索引是最常见的索引类型,它允许一列中出现重复的值。唯一索引则要求一列中的值必须唯一,不能有重复的值。主键索引是一种特殊的唯一索引,它用于唯一标识数据表中的每一行。全文索引用于搜索数据库中的文本内容。 索引可以帮助 MySQL 加快查询速度,但是它也有一定的开销。在创建索引时,MySQL 需要为索引中的每一行建立一个索引,并在插入 ### 回答2: MySQL索引原理是通过建立索引来加快数据的查找和检索速度。索引是在表中的一个数据结构,它包含了对数据的引用地址,能够使数据库系统快速定位到需要查询的数据记录,从而提高查询效率。 MySQL中常见的索引类型有主键索引、唯一索引和普通索引。主键索引是一种唯一性索引,用于标识表中的每一行数据,保证每一行数据都有一个唯一的标识,加速对数据的操作。唯一索引保证索引列中的数据是唯一的,确保数据的完整性。普通索引是最基本的索引类型,用于加速对数据的查询操作。 MySQL索引原理可以分为B+树索引和哈希索引两种。B+树索引MySQL最常用的索引类型,它采用B+树数据结构来存储索引数据,通过使用该数据结构可以快速定位到数据所在的磁盘块,从而减少磁盘IO,提高查询效率。B+树索引适用于范围查找、排序和分组等操作。哈希索引是将数据的键值通过哈希函数计算得到一个唯一的哈希值,将这个哈希值与数据存储的位置建立映射关系,从而实现快速的数据定位和查找。哈希索引适用于等值查询,在某些特定场景下具有较高的查询效率。 创建索引可以加速查询,但同时也会增加写入操作的开销。索引的维护需要占用额外的空间和时间,当数据发生变动时,需要更新索引的信息。因此,在创建索引时需要考虑到实际的读写比例,避免过多的索引导致性能下降。另外,索引的选择也需要根据具体的应用场景来决定,不同的查询操作需要选择不同的索引类型,以提高查询效率。 ### 回答3: MySQL索引原理主要是通过B树(B-Tree)和哈希索引来实现的。 B树是一种平衡的多路搜索树,MySQL的B树索引是指通过对关键字进行排序,将数据存储在需要的页中的一种索引结构。B树索引适用于频繁插入和删除数据的情况,因为B树的平衡性使得它的高度相对较低,查询速度较快。对于InnoDB引擎来说,默认的索引类型为B+树。 B+树是B树的一种变种,它将数据存储在叶子节点上,而非内部节点。叶子节点之间通过指针连接起来,提高了范围查询的效率。B+树索引也支持从左到右的最长前缀匹配,可以用于处理模糊查询。 哈希索引是将索引值通过一个哈希函数计算出一个哈希码,然后根据哈希码在索引表中进行查找的索引结构。哈希索引适用于等值查询,它具有快速的查找速度。但哈希索引对范围查询的支持较差,而且在大数据量的情况下,可能导致哈希冲突,影响性能。 MySQL还支持全文索引,它是一种用于快速搜索文本内容的索引方式。全文索引基于倒排列表实现,在建立全文索引时将文本内容进行分词,并存储每个词在哪些文档中出现。通过全文索引,可以实现对文本内容的全文搜索。 在使用MySQL索引时,需要根据业务需求创建合适的索引,避免创建过多或不必要的索引,因为索引会占用存储空间,并且在插入、更新和删除数据时会有额外的开销。同时,需要定期进行索引的优化和维护,以保证查询的性能和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

s_wei_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值