• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

奋斗的软件工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

深入理解MySQL索引:从原理到实践

深入理解MySQL索引:从原理到实践

在数据库管理系统中,MySQL因其高效性和可靠性而被广泛使用。随着数据量的不断增长,查询性能成为一个关键问题。为了解决这一问题,MySQL提供了索引机制。本文将深入探讨MySQL索引的原理、分类、语法、优缺点、创建原则,以及其底层数据结构,帮助读者全面理解并有效地使用索引。

1. MySQL性能分析

1.1 数据库查询效率低下的原因

在项目开发中,我们通常关注业务需求和功能的实现,但随着数据量的增加,数据库的查询性能可能会下降。为了提高数据库的性能,有两种优化方式:

  1. 硬优化:在软优化之后性能仍然低下时,可以考虑通过增加硬件资源(如购买更强大的服务器)来提升性能。
  2. 软优化:通过优化数据库操作和设计来提高性能,例如使用索引。

1.2 执行次数较多的SQL语句

在数据库中,执行次数较多的SQL语句可以分为两类:

  1. 查询密集型:这类查询通常占据了80%的执行次数,可以通过索引来优化。
  2. 修改密集型:这类操作通常在订单系统中较为常见,例如用户增加商品、修改商品数量等。对于这类操作,可以使用ElasticSearch(ES)等技术来优化。

1.3 查看SQL语句的执行效率

通过查看累计插入和返回数据条数,可以判断当前数据库是查询密集型还是修改密集型。使用以下SQL语句可以查看相关信息:

show global status like 'Innodb_rows%';

2. MySQL索引介绍

2.1 什么是索引

索引是帮助MySQL高效获取数据的数据结构(有序)。它通过特定的查找算法来快速定位数据,从而提高查询效率。

2.2 MySQL索引分类

MySQL索引主要分为以下几类:

  • 主键索引:主键约束+提高查询效率。
  • 唯一索引:唯一约束+提高查询效率。
  • 普通索引:仅提高查询效率。
  • 组合索引:多个字段组成的索引。
  • 全文索引:用于全文搜索,通常使用Solr或ElasticSearch。
  • Hash索引:根据key-value进行快速查找。

3. MySQL索引语法

3.1 创建索引

3.1.1 在已有表的字段上直接创建

-- 创建普通索引
create index 索引名 on 表名(字段);

-- 创建唯一索引
create unique index 索引名 on 表名(字段);

-- 创建普通组合索引
create index 索引名 on 表名(字段1,字段2,..);

-- 创建唯一组合索引
create unique index 索引名 on 表名(字段1,字段2,..);

3.1.2 在已有表的字段上修改表时指定

-- 添加主键索引
alter table 表名 add primary key(字段);

-- 添加唯一索引
alter table 表名 add unique(字段);

-- 添加普通索引
alter table 表名 add index(字段);

3.1.3 创建表时指定

CREATE TABLE student3(
 id INT PRIMARY KEY AUTO_INCREMENT, -- 主键索引
 name VARCHAR(32),
 telephone VARCHAR(11) UNIQUE, -- 唯一索引
 sex VARCHAR(5),
 birthday DATE,
 INDEX(name) -- 普通索引
);

3.2 查看索引

show index from 表名;

3.3 删除索引

-- 直接删除
drop index 索引名 on 表名;

-- 修改表时删除
alter table 表名 drop index 索引名;

4. 索引的优缺点

4.1 优势

  1. 提高数据检索效率:类似于书籍的目录索引,降低数据库的IO成本。
  2. 降低数据排序成本:通过索引列对数据进行排序,降低CPU的消耗。

4.2 劣势

  1. 建立和维护索引需要时间:随着数据量的增加,时间成本也会增加。
  2. 占用物理存储空间:索引需要额外的存储空间。
  3. 动态维护索引:在对表中的数据进行修改时,索引需要进行动态维护,这会增加数据库的维护成本。

5. 索引创建原则

  1. 字段内容可识别度不能低于70%:字段内数据唯一值的个数不能低于70%。
  2. 经常使用where条件搜索的字段:例如user表的id、name等字段。
  3. 经常使用表连接的字段:可以加快连接的速度。
  4. 经常排序的字段:因为索引已经是排过序的,可以加快排序查询速度。

6. 索引的数据结构

6.1 概述

索引是帮助MySQL高效获取排好序的数据结构。MySQL索引的底层数据结构主要有以下几种:

  1. 二叉查找树:左边的子节点比父节点小,右边的子节点比父节点大。
  2. 红黑树:平衡二叉树,通过左旋、右旋、变色来保持平衡。
  3. BTree:多路平衡搜索树,一个节点可以有多个元素。
  4. B+Tree:优化BTree,非叶子节点存储索引+指针,叶子节点存储索引+数据或数据的地址值。

6.2 B+Tree的优势

  1. 降低树的高度:B+Tree通过增加树的宽度来降低树的高度,从而减少磁盘IO次数。
  2. 支持范围查询:叶子节点按照索引排好序,支持范围查找,速度快。
  3. 根节点加载到内存:MySQL将根节点加载到内存中,每张表有一个根节点,大小是16KB,从而减少磁盘IO次数。

6.3 MySQL中的B+Tree

MySQL中的B+Tree在经典B+Tree的基础上,增加了指向相邻叶子节点的链表指针,提高了区间访问的性能。

6.4 详细介绍B+Tree

6.4.1 二叉查找树

二叉查找树(Binary Search Tree, BST)是一种常见的数据结构,具有以下特点:

  • 左子树的所有节点值小于根节点的值。
  • 右子树的所有节点值大于根节点的值。
  • 左右子树也分别为二叉查找树。

然而,二叉查找树在某些情况下可能会退化成链表,导致查找效率降低。例如,如果数据是按顺序插入的,二叉查找树会变成一个线性结构,查找效率会降低到O(n)。

6.4.2 红黑树

红黑树(Red-Black Tree)是一种自平衡的二叉查找树,通过颜色标记和旋转操作来保持树的平衡。红黑树具有以下特点:

  • 每个节点要么是红色,要么是黑色。
  • 根节点是黑色。
  • 每个叶子节点(NIL节点)是黑色。
  • 如果一个节点是红色的,则它的两个子节点都是黑色的。
  • 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

红黑树通过这些规则保持了树的平衡,查找、插入和删除操作的时间复杂度均为O(log n)。然而,红黑树的高度仍然较高,对于大规模数据,磁盘IO次数仍然较多。

6.4.3 BTree

BTree(Balanced Tree)是一种多路平衡搜索树,具有以下特点:

  • 每个节点可以有多个子节点。
  • 所有叶子节点在同一层。
  • 每个节点包含多个键值对,键值对之间有序排列。

BTree通过增加树的宽度来降低树的高度,从而减少磁盘IO次数。每个节点可以存储多个元素,每个元素由索引、指针域和数据域组成。一个节点的大小通常为16KB,假设一个元素的大小为1KB,那么一个节点可以存储16个元素。

6.4.4 B+Tree

B+Tree是BTree的优化版本,具有以下特点:

  • 非叶子节点只存储索引和指针,不存储数据。
  • 叶子节点存储所有索引和数据(或数据的地址值)。
  • 叶子节点之间通过链表连接,支持范围查询。

B+Tree的优势在于:

  1. 降低树的高度:通过增加树的宽度,B+Tree可以将树的高度控制在较低的水平,从而减少磁盘IO次数。
  2. 支持范围查询:叶子节点按照索引排好序,并且通过链表连接,支持快速的范围查询。
  3. 根节点加载到内存:MySQL将根节点加载到内存中,每张表有一个根节点,大小为16KB,从而减少磁盘IO次数。

6.5 B+Tree的详细结构

6.5.1 非叶子节点

非叶子节点存储索引和指针,不存储数据。每个非叶子节点包含多个键值对,键值对之间有序排列。每个键值对由索引和指针组成,索引用于快速定位数据,指针指向下一层的节点。

6.5.2 叶子节点

叶子节点存储所有索引和数据(或数据的地址值)。叶子节点之间通过链表连接,支持范围查询。叶子节点按照索引排好序,可以快速定位数据。

6.5.3 节点大小

一个节点的大小通常为16KB,假设一个元素的大小为1KB,那么一个节点可以存储16个元素。通过增加树的宽度,B+Tree可以将树的高度控制在较低的水平,从而减少磁盘IO次数。

6.6 B+Tree的查找过程

  1. 从根节点开始:MySQL将根节点加载到内存中,从根节点开始查找。
  2. 定位到叶子节点:通过索引和指针,定位到叶子节点。
  3. 查找数据:在叶子节点中查找数据,如果数据存储在叶子节点中,直接返回数据;如果数据存储在数据的地址值中,通过地址值定位到数据。

6.7 B+Tree的优势总结

  1. 降低树的高度:通过增加树的宽度,B+Tree可以将树的高度控制在较低的水平,从而减少磁盘IO次数。
  2. 支持范围查询:叶子节点按照索引排好序,并且通过链表连接,支持快速的范围查询。
  3. 根节点加载到内存:MySQL将根节点加载到内存中,每张表有一个根节点,大小为16KB,从而减少磁盘IO次数。

7. 总结

通过合理地使用索引,可以显著提高MySQL的查询效率。然而,索引的创建和维护也需要权衡其优缺点。在实际应用中,应根据具体的业务需求和数据特点,选择合适的索引策略,以达到最佳的性能优化效果。了解索引的底层数据结构和工作原理,有助于更好地进行数据库优化和性能调优。

posted on 2024-11-22 13:57  周政然  阅读(340)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3