MySQL索引(面试可用)

什么是索引?

索引本质上是一种通过减少查询需要遍历的行数,加快查询性能的数据结构,避免数据库进行全表扫描,节约大量时间。

MySQL 官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。

提取句子主干,就可以得到索引的本质:索引是数据结构。

索引的优点:

  • 减少查询需要检索的行数,加快查询速度,避免全表查询,这是索引最主要的原因;
  • 通过创建唯一性索引,保证数据库中每一行数据的唯一性;
  • 在使用分组和排序子句进行数据检索时,可以显著减少查询中分组和排序的时间;
  • 能够加快表和表之间的连接。

索引的缺点:

  • 创建索引和维护索引需要耗费时间,并且时间随数据量的增加而增加;
  • 索引需要占用物理空间,如果创建聚簇索引,需要占用的空间会更大;
  • 对数据进行增、删、改时,索引需要动态维护,降低了数据的维护速度。

索引的类型有哪些?

(1)从物理结构上可以分为聚簇索引和非聚簇索引两类:

  • 聚簇索引指索引的键值的逻辑顺序与表中相应行的物理顺序一致,即每张表只能有一个聚簇索引,也就是主键索引;
  • 非聚簇索引与聚簇索引相反,逻辑顺序与数据行的物理顺序不一致。

(2)从应用上可以分为以下几类:

  • 主键索引:索引列中的值必须是唯一的,不允许有空值;

    # 创建主键索引语句
    ALTER TABLE `table_name` ADD PRIMARY KEY (`column_name`);
    
  • 唯一索引:索引列中的值必须是唯一的,但允许有空值;

    # 创建唯一索引语句
    ALTER TABLE `table_name` ADD UNIQUE index_name (`column_name`);
    
    CREATE UNIQUE INDEX index_name ON `table_name` (`column_name`(length));
    
  • 普通索引:MySQL中的基本索引类型,没有什么限制,允许在定义索引的列中插入重复值和空值;

    # 创建普通索引语句
    ALTER TABLE `table_name` ADD INDEX index_name (`column_name`(length));
    
    CREATE INDEX index_name ON `table_name` (`column_name`(length));
    
  • 组合索引:组合表中多个字段创建的索引,遵守最左前缀匹配规则,即使用 where 时条件要按照建立索引的时候字段的排列方式放置索引才会生效;

    # 创建组合索引语句
    CREATE INDEX index_name ON `table_name` (`column_name_1`, `column_name_2`);
    
  • 全文索引:它查找的是文本中的关键词,主要用于全文检索。

补充索引语句:

# 查看索引语句
SHOW INDEX FROM `table_name`;

# 删除索引语句1
DROP INDEX index_name ON `table_name`;

# 删除索引语句2
ALTER TABLE `table_name` DROP INDEX index_name;

创建索引原则有哪些?

通俗来讲,索引有四个原则:

  • 索引不是越多越好;
  • 不要对经常变动的数据加索引;
  • 小数据量的表不需要加索引;
  • 索引一般加在经常用来查询的字段上。

根据上述原则可以具体区分为应该创建索引的列和不应该创建索引的列:

应该创建索引的列:

  • 在经常需要搜索查询的列上创建索引,可以加快搜索的速度;
  • 在作为主键的列上创建索引,强制该列的唯一性和组织表中数据的排列结构;
  • 在经常用在连接(JOIN)的列上创建索引,这些列主要是一些外键,可以加快连接的速度;
  • 在经常需要根据范围(<,<=,=,>,>=,BETWEEN,IN)进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的;
  • 在经常需要排序(ORDER BY)、分组(GROUP BY)、去重(DISTINCT )、联合(UNION)等操作的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间;
  • 在经常使用在 WHERE 子句中的列上面创建索引,加快条件的判断速度。

不应该创建索引的列:

  • 对于那些在查询中很少使用或者参考的列不应该创建索引:这些列很少使用到,创建索引不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求;
  • 对于那些只有很少数据值或者重复值多的列不应该增加索引:这些列的取值很少,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大,增加索引并不能明显加快检索速度;
  • 对于那些定义为 text,image 和 bit 数据类型的列不应该增加索引:这些列的数据量要么相当大,要么取值很少;
  • 当该列修改性能要求远远高于检索性能时不应该创建索引:修改性能和检索性能是互相矛盾的;
  • 数量级在百万以内的小表不应该创建索引:由于数据较小,查询花费的时间可能比遍历索引的时间短,索引并不会产生优化效果。

索引的数据结构有哪些?

MySQL 中常用的是 Hash 和 B+ 树索引。

  • Hash 索引底层是 Hash 表,进行查询时调用 Hash 函数获取到相应的键值(对应地址),然后回表查询获得实际数据;
  • B+ 树索引底层实现原理是多路平衡查找树,对于每一次的查询都是从根节点出发,查询到叶子节点方可以获得所查键值,最后查询判断是否需要回表查询。

为什么 B+ 树比 B 树更适合应用于数据库索引?

  • B+ 树减少了 IO 次数
    由于索引文件很大因此索引文件存储在磁盘上,B+ 树的非叶子结点只存关键字不存数据,因而单个页可以存储更多的关键字,即一次性读入内存的需要查找的关键字也就越多,磁盘的随机 I/O 读取次数相对就减少了。
  • B+ 树查询效率更稳定
    由于数据只存在在叶子结点上,所以查找效率固定为 O(log n),所以 B+ 树的查询效率相比B树更加稳定。
  • B+ 树更加适合范围查找
    B+ 树叶子结点之间用链表有序连接,所以扫描全部数据只需扫描一遍叶子结点,利于扫库和范围查询;B 树由于非叶子结点也存数据,所以只能通过中序遍历按序来扫。也就是说,对于范围查询和有序遍历而言,B+ 树的效率更高。

猜你喜欢

转载自blog.csdn.net/wyc837279588/article/details/128603751