DukeDuke
主页
文档转换
关于我们
主页
文档转换
关于我们
  • Redis

    • Redis简介
    • Redis(单机)安装
    • Redis配置
    • Redis数据结构
    • RDB、AOF 和混合持久化机制
    • Redis内存管理
    • Redis缓存一致性
    • Redis缓存穿透
    • Redis缓存击穿
    • Redis缓存雪崩
    • Redis Lua脚本
    • Redis主从复制
    • Redis哨兵模式
    • Redis集群
    • Redis数据分片
    • Redis CPU使用率过高
    • Redis面试题
  • MySQL

    • MySQL简介
    • MySQL安装
    • MySQL配置
    • MYSQL日常维护
    • MYSQL优化-慢查询
    • MYSQL优化-索引
    • MYSQL数据库设计规范

数据库优化 - 索引

索引的工作原理

提示

想象一下,如果我们要在一本没有目录的书中查找某个主题,我们需要从头到尾翻阅整本书。这就像是在没有索引的数据库表中进行全表扫描。而有了索引,就像有了目录,我们可以直接翻到相关页面,大大节省了查找时间。

相关信息

MySQL 支持多种索引数据结构,主要包括 BTree 和 Hash 。不同的索引结构适用于不同的场景。

Innodb 和 MyISAM 默认的索引是 Btree 索引。

常见的索引类型

1. 主键索引(Primary Key)

主键索引是表中最基本的索引类型,它要求索引列的值必须唯一且不能为空。每个表只能有一个主键索引。 主键索引适用于:

  • 表的主键字段
  • 需要唯一标识的字段
  • 经常用于关联查询的字段

2. 唯一索引(Unique Index)

唯一索引要求索引列的值必须唯一,但允许有空值。这种索引常用于确保数据的唯一性。 唯一索引适用于:

  • 用户邮箱
  • 手机号码
  • 身份证号
  • 其他需要唯一性的业务字段

3. 普通索引(Normal Index)

普通索引是最基本的索引类型,它没有任何限制,可以包含重复值和空值。 普通索引适用于:

  • 经常用于查询条件的列
  • 经常用于排序的列
  • 经常用于连接的列
  • 区分度高的列

4. 空间索引(Spatial Index)

空间索引是专门用于处理地理空间数据的索引类型。它主要用于存储和查询具有地理位置信息的数据,如点、线、面等几何对象。MySQL 使用 R-tree 数据结构来实现空间索引。

使用空间索引时,需要使用空间数据类型(如 GEOMETRY、POINT、LINESTRING、POLYGON 等)和空间函数(如 ST_Distance、ST_Contains 等)。

5. 全文索引(Fulltext Index)

全文索引是一种特殊的索引类型,专门用于全文搜索。它能够对文本内容进行分词,并建立索引,支持自然语言搜索。 全文索引适用于:

  • 文章内容搜索
  • 产品描述搜索
  • 评论内容搜索
  • 需要模糊匹配的场景

注意:全文索引只能用于 CHAR、VARCHAR 和 TEXT 类型的列,且只支持 InnoDB 和 MyISAM 存储引擎。

索引的使用

创建索引

CREATE [UNIQUE|FULLTEXT|SPATIAL|NORMAL] INDEX index_name ON table_name (column1, column2, ...);

其中,UNIQUE 表示创建唯一索引,FULLTEXT 表示创建全文索引,SPATIAL 表示创建空间索引,NORMAL 表示创建普通索引, index_name 是索引的名称,table_name 是要创建索引的表名,(column1, column2, ...) 是要创建索引的列名。

查看索引

SHOW INDEX FROM table_name;

hsv

字段名说明注释
Table表名显示索引所属的表名
Non_unique是否唯一0 表示唯一索引,1 表示非唯一索引
Key_name索引名称显示索引的名称,PRIMARY 表示主键索引
Seq_in_index索引中的列序号表示索引中的列顺序,从 1 开始
Column_name列名索引包含的列名
Collation排序方式A 表示升序,NULL 表示无排序
Cardinality基数索引中唯一值的数量估计值,用于优化器选择索引
Sub_part索引前缀长度如果只索引列的前缀,则显示前缀长度,NULL 表示索引整个列
Packed是否压缩表示索引是否被压缩,NULL 表示未压缩
Null是否允许 NULLYES 表示允许 NULL 值,NO 表示不允许
Index_type索引类型显示索引的类型,如 BTREE、HASH 等
Comment注释索引的注释信息
Index_comment索引注释创建索引时添加的注释
Visible索引是否可见YES 表示索引可见,NO 表示索引不可见(MySQL 8.0 新增特性)
Expression表达式索引显示用于创建索引的表达式(MySQL 8.0 新增特性)

删除索引

索引的注意事项

  1. 索引会占用额外的存储空间
  2. 索引会降低写入性能(INSERT、UPDATE、DELETE 操作)
  3. 过多的索引会增加数据库维护成本
  4. 小表不需要建立索引
  5. 频繁更新的列不适合建立索引

实际案例分析

假设我们有一个用户表,包含以下字段:id、username、email、phone、create_time。根据不同的查询需求,我们可以这样设计索引:

  1. 主键索引:id(自动创建)
  2. 唯一索引:phone(确保手机号唯一)
CREATE UNIQUE INDEX phone_index ON sys_user(phone)
  1. 普通索引:username(用于用户名查询)
CREATE INDEX username_index ON sys_user(username)
  1. 复合索引:(phone, create_time)(用于按手机号和创建时间查询)
CREATE INDEX phone_create_time_index ON sys_user(phone,create_time)

这样的索引设计既保证了查询效率,又避免了过度索引带来的性能问题。

总结

索引是数据库优化的重要手段,合理使用索引可以显著提高查询性能。但索引不是万能的,需要根据实际业务场景和查询需求来设计。在创建索引时,要权衡查询性能和写入性能,找到最适合的平衡点。

最近更新:: 2026/4/17 13:21
Contributors: Duke
Prev
MYSQL优化-慢查询
Next
MYSQL数据库设计规范