150道MySQL高频面试题,学完吊打面试官--如何实现索引机制
前言
本专栏为150道MySQL大厂高频面试题讲解分析,这些面试题都是通过MySQL8.0官方文档和阿里巴巴官方手册还有一些大厂面试官提供的资料。
MySQL应用广泛,在多个开发语言中都处于重要地位,所以最好都要掌握MySQL的精华面试题,这也是面试官最喜欢问的,现在面试官在面试的时候更关心的是某个技术点的深度,所以专栏的内容也会从底层开始讲解,本专栏会一直不断的进行更新,欢迎大家一起交流学习。
上图就是当前MySQL主流面试题的几个方向,本篇为索引篇
MySQL如何实现索引机制
索引的基本概念
索引是数据库表中一列或多列值的排序列表,通过索引可以更快地查找表中的记录。索引主要分为以下几类:
- 主键索引(Primary Key Index):主键是表中每行记录的唯一标识,因此主键索引也是唯一的。
- 唯一索引(Unique Index):类似于主键索引,但允许有一个空值(NULL)。
- 普通索引(Normal Index):最基础的索引,没有任何限制。
- 全文索引(Full-Text Index):用于全文搜索,只能在CHAR、VARCHAR和TEXT类型列上创建。
- 组合索引(Composite Index):在表的多个列上创建索引,以提高基于这些列的查询性能。
索引的存储类型
MySQL支持多种存储引擎,不同存储引擎的索引实现机制可能有所不同。以最常用的InnoDB存储引擎为例,它主要使用B+树来存储索引。
- B+树索引:InnoDB默认使用B+树来实现索引。B+树是一种平衡树,叶子节点之间通过链表相连,非常适合范围查询和顺序扫描。
- 哈希索引:在某些情况下,可以使用哈希索引来提高查找速度,但哈希索引不支持范围查询。哈希索引一般是配合B+树索引一起使用的,但是哈希索引不能通过手动创建出来,是由系统自动生成。
- 全文索引:InnoDB也支持全文索引,使用倒排索引结构,主要用于全文搜索。
而经常使用的就是B+树索引结构,B+树索引结构是一种树形数据结构。
B+树和二叉树的区别
B+树和二叉树都是树形数据结构,但它们在结构、特性和应用场景上存在显著差异。
B+树
B+树是一种平衡多路查找树,是B树的一种变体。它的特点包括:
- 结构:B+树由根节点、内部节点和叶子节点组成。每个节点可以有多个子节点,且内部节点仅包含索引信息,不包含实际数据。所有数据都保存在叶子节点中,并且叶子节点之间通过指针相连,形成一个有序链表。
- 特性:B+树能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。由于内部节点不保存数据,所以能在内存中存放更多索引,增加缓存命中率。另外,因为叶子节点相连,遍历操作很方便,而且数据也具有顺序性,便于区间查找。
- 应用场景:B+树常用于数据库和操作系统的文件系统中,如NTFS、ReiserFS、XFS等文件系统都在使用B+树作为元数据索引。
二叉树
二叉树是一种每个节点最多有两个子节点的树形数据结构。它的特点包括:
- 结构:二叉树由根节点和若干子节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。
- 特性:二叉树可以是平衡的,也可以是不平衡的。平衡二叉树通过保持树的平衡来提高查找效率。二叉搜索树(BST)是一种特殊的二叉树,其中左子树的所有节点值小于根节点值,右子树的所有节点值大于根节点值。这种结构使得二叉搜索树的查找效率接近二分查找。
- 应用场景:二叉树广泛应用于各种算法和数据结构中,如二叉搜索树、平衡二叉树(如AVL树、红黑树等)等。它们常用于实现集合、映射、优先级队列等数据结构,并在搜索、排序、插入和删除等操作中表现出色。
区别
- 结构差异:B+树是平衡多路查找树,每个节点可以有多个子节点;而二叉树是每个节点最多有两个子节点的树形数据结构。
- 内部节点存储内容:B+树的内部节点仅包含索引信息,不包含实际数据;而二叉树的节点通常包含关键字和对应的数据值(在二叉搜索树中,节点还包含指向子树的指针)。
- 叶子节点连接方式:B+树的叶子节点通过指针相连,形成一个有序链表,便于区间查找和遍历;而二叉树的叶子节点通常不直接相连。
- 应用场景:B+树常用于数据库和文件系统的索引结构中,因其良好的平衡性和有序性而适合大规模数据的查找和遍历;而二叉树则广泛应用于各种算法和数据结构中,如集合、映射、优先级队列等。
索引的创建和使用
在MySQL中,可以通过CREATE INDEX语句来创建索引。
CREATE INDEX idx_user_name ON users(name);
这将在users表的name列上创建一个名为idx_user_name的普通索引。
主键索引和唯一索引可以在创建表时通过PRIMARY KEY和UNIQUE关键字定义,也可以在表创建后通过ALTER TABLE语句添加。
索引的维护
索引的维护包括更新、删除和重建索引等操作。当表中的数据发生变化时,索引也需要相应地更新。因此,频繁更新数据可能会影响索引的性能。
更新索引:
MySQL会自动在数据更新时更新相关索引。
删除索引:
可以通过DROP INDEX语句删除不再需要的索引。
DROP INDEX idx_user_name ON users;
重建索引:
在某些情况下,重建索引可以提高查询性能。可以使用OPTIMIZE TABLE语句来重建表的物理结构和索引。
索引的分类及实现方式
MySQL中的索引根据其功能和结构可分为以下几类:
主键索引
- 功能:确保表中每条记录的唯一性,不允许有空值。
- 实现方式:通常在创建表时设置,MySQL会自动为该列创建主键索引,不需要手动创建。在InnoDB存储引擎中,主键索引是聚簇索引,叶子节点存放的是主键值和数据行本身。
单列索引(普通索引)
- 功能:仅对单个列创建索引。
- 实现方式:一个表可以拥有多个单列索引。可以通过CREATE INDEX语句手动创建。
联合索引(组合索引)
- 功能:将多个单列索引组合在一起,形成的多列索引,可以提高多条件查询的效率。
- 实现方式:在创建表或修改表时,通过指定多个列来创建联合索引。
唯一索引
- 功能:要求索引列的值必须唯一,但允许有空值。对于联合唯一索引,要求列值的组合唯一。
- 实现方式:可以通过CREATE UNIQUE INDEX语句手动创建。
外键索引
- 功能:主要用于InnoDB存储引擎,确保数据一致性、完整性,支持级联操作。
- 实现方式:通过添加外键约束来实现。
BTree索引
- 功能:最常用的索引结构,适用于大多数查询场景。
- 实现方式:InnoDB和MyISAM存储引擎都默认使用基于B+Tree的索引结构。B+Tree索引具有平衡性,能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。
Hash索引
- 功能:基于哈希表实现,适用于精确查询,但不支持范围查询。
- 实现方式:Memory存储引擎默认使用的索引结构。
R-tree索引(空间索引)
- 功能:主要用于处理地理空间数据类型,如GIS应用。
- 实现方式:MyISAM引擎中的一种特殊索引。
Full-text索引(全文索引)
- 功能:用于全文检索,快速匹配大文本的内容。
- 实现方式:MyISAM引擎原生支持,InnoDB在5.6版本后也开始支持此类型的索引,主要用于文本字段中的关键字搜索。
InnoDB存储引擎中的索引特性
聚簇索引
- 特点:叶子节点存放的是主键值和数据行本身。在InnoDB存储引擎中,主键索引是聚簇索引。
- 优势:数据访问更快,因为聚簇索引将数据行和索引保存在同一棵B+树中。
- 劣势:插入性能受顺序影响,乱序插入会导致页面分裂,影响性能;更新主键代价高,因为数据行会被移动。
辅助索引
- 特点:InnoDB存储引擎中的辅助索引是聚簇索引之外的非聚簇索引,例如复合索引、前缀索引等。叶子节点存储的是主键值,而不是数据行本身。
- 访问方式:需要二次查找才能获取数据。首先通过辅助索引找到主键值,然后使用主键值通过聚簇索引找到对应的数据页,最后在数据页中通过二分法查找到具体的数据行。
二级索引的扩展
- 特点:InnoDB的二级索引会自动补齐主键,将主键列追加到二级索引列后面。这样做可以减少大量的二级索引维护工作,因为当数据行移动或者发生页分裂的时候,无需更新二级索引。
- 优化:在设计主键的时候,常见的一条设计原则是要求主键字段尽量简短,以避免二级索引过大(因为二级索引会自动补齐主键字段)。