MYSQL——基础知识(MYSQL 索引)

目录

前言

一、索引是什么?

[二、MySQL 索引的主要类型](#二、MySQL 索引的主要类型)

三、如何创建索引?

四、删除索引

五、查看索引信息

六、索引使用最佳实践

七、索引的代价与权衡

八、高级技巧:如何验证索引是否生效?

小结


前言

在数据库世界中,索引(Index) 是提升查询效率的"高速公路"。没有索引的查询如同在茫茫人海中逐个寻找目标------耗时且低效;而有了合理设计的索引,MySQL 就能像兰博基尼一样飞驰直达目的地。

本文将系统讲解 MySQL 索引的核心概念、类型、创建与管理方法、使用原则及常见误区,助你构建高性能数据库应用。


一、索引是什么?

类比理解

  • 书籍目录:通过"拼音索引"快速定位"张三"在哪一页;
  • 字典部首检字表:无需翻遍全书,直接跳转到目标字;
  • 数据库索引 :通过 B+ 树等数据结构,快速定位满足 WHERE 条件的数据行。

技术本质

索引是独立于数据表的物理结构,存储了:

  • 索引列的值(如 email = 'user@example.com'
  • 指向对应数据行的指针(或主键值)

用途 :将 O(n) 全表扫描 优化为 O(log n) 树查找


二、MySQL 索引的主要类型

类型 特点 适用场景
普通索引(INDEX) 允许重复值和 NULL 加速 WHERE、JOIN、ORDER BY
唯一索引(UNIQUE) 列值必须唯一(NULL 可多次出现) 保证业务唯一性(如邮箱、身份证)
主键索引(PRIMARY KEY) 特殊的唯一索引,不允许 NULL,一张表仅一个 表的唯一标识
组合索引(Composite Index) 多列联合索引 复合查询条件(如 (status, create_time)
全文索引(FULLTEXT) 支持关键词搜索(MyISAM / InnoDB 5.6+) 文章内容、商品描述搜索
空间索引(SPATIAL) 用于地理数据(如 POINT、POLYGON) 地图、LBS 应用

三、如何创建索引?

1. 创建普通索引

(1) 使用 CREATE INDEX
sql 复制代码
-- 在 students 表的 name 列创建索引
CREATE INDEX idx_name ON students (name);
(2) 使用 ALTER TABLE
sql 复制代码
-- 为 employees 表添加 age 索引
ALTER TABLE employees ADD INDEX idx_age (age);
(3) 建表时直接定义
sql 复制代码
CREATE TABLE students (
    id INT PRIMARY KEY,
    name VARCHAR(50),
    age INT,
    INDEX idx_age (age)  -- 普通索引
);

2. 创建唯一索引

(1) 使用 CREATE UNIQUE INDEX
sql 复制代码
-- 确保 email 唯一
CREATE UNIQUE INDEX idx_email ON employees (email);
(2) 使用 ALTER TABLE
sql 复制代码
ALTER TABLE employees 
ADD CONSTRAINT uk_email UNIQUE (email);
(3) 建表时定义
sql 复制代码
CREATE TABLE employees (
    id INT PRIMARY KEY,
    email VARCHAR(100) UNIQUE  -- 自动创建唯一索引
);
-- 或显式命名
CREATE TABLE employees (
    id INT PRIMARY KEY,
    email VARCHAR(100),
    UNIQUE uk_email (email)
);

注意:若表中已存在重复值,创建唯一索引会失败!


3. 创建组合索引(多列索引)

sql 复制代码
-- 查询常按 status 和 create_time 过滤
ALTER TABLE orders 
ADD INDEX idx_status_time (status, create_time);

-- 查询示例(能命中索引)
SELECT * FROM orders 
WHERE status = 'paid' AND create_time > '2025-01-01';

最左前缀原则

组合索引 (A, B, C) 能加速以下查询:

  • WHERE A = ?
  • WHERE A = ? AND B = ?
  • WHERE A = ? AND B = ? AND C = ?
    不能加速 WHERE B = ?WHERE C = ?

四、删除索引

sql 复制代码
-- 方法1:DROP INDEX
DROP INDEX idx_name ON students;

-- 方法2:ALTER TABLE
ALTER TABLE students DROP INDEX idx_name;

-- 删除主键(特殊语法)
ALTER TABLE students DROP PRIMARY KEY;

删除前请确认:

  • 该索引是否被重要查询依赖;
  • 是否有外键引用(主键不可直接删)。

五、查看索引信息

sql 复制代码
-- 查看 students 表的所有索引
SHOW INDEX FROM students\G

-- 关键字段解读:
-- Key_name: 索引名称
-- Column_name: 索引列
-- Non_unique: 0=唯一, 1=非唯一
-- Seq_in_index: 列在组合索引中的位置
-- Cardinality: 基数(值越接近行数,选择性越高)
-- Collation: 排序方式(A=升序)

六、索引使用最佳实践

应该建索引的场景

  1. 频繁作为查询条件的列WHERE user_id = ?
  2. JOIN 关联字段orders.user_id = users.id
  3. ORDER BY / GROUP BY 的列
  4. 需要保证唯一性的字段(用唯一索引)

不适合建索引的场景

  1. 数据量很小的表(< 1000 行,全表扫描更快)
  2. 频繁更新的列(索引维护成本高)
  3. 低选择性字段 (如 gender 只有男/女)
  4. 包含大量重复值的列

索引设计黄金法则

原则 说明
少而精 避免过度索引,每个表通常 3~5 个足够
覆盖查询 尽量让索引包含 SELECT 所需字段(避免回表)
前缀索引 对长文本(如 VARCHAR(255))可建前缀索引: INDEX idx_url (url(20))
避免函数索引 WHERE YEAR(create_time) = 2025 无法用索引,应改写为范围查询

七、索引的代价与权衡

优势 劣势
查询速度大幅提升 占用额外磁盘空间
支持快速排序/分组 INSERT/UPDATE/DELETE 变慢(需维护索引)
保证数据唯一性 过多索引导致优化器选择困难

经验公式

写多读少 → 少建索引;

读多写少 → 合理建索引。


八、高级技巧:如何验证索引是否生效?

使用 EXPLAIN 分析执行计划:

sql 复制代码
EXPLAIN SELECT * FROM employees WHERE email = 'test@example.com';

关注关键字段:

  • type : const / ref 表示命中索引,ALL 表示全表扫描;
  • key: 实际使用的索引名;
  • rows: 扫描行数(越小越好);
  • Extra : 出现 Using index 表示"覆盖索引",性能最优。

小结

"高频查询建索引,唯一约束用 UNIQUE;
组合索引遵左前,小表低选莫乱加;
增删改多慎索引,EXPLAIN 验证是王道!"

合理使用索引,是数据库性能优化的第一步,也是最重要的一步。掌握它,你就掌握了让 MySQL 飞起来的钥匙!

相关推荐
Zhu_S W2 小时前
MySQL大表优化完全指南
数据库·mysql
Hx_Ma162 小时前
mybatis练习2
java·数据库·mybatis
CN-David2 小时前
CentOS搭建Mycat中间件
linux·mysql·中间件·centos·mariadb
星辰_mya2 小时前
Kafka Producer 发送慢 → TPS 骤降 90%
java·数据库·kafka
花间相见2 小时前
【Ubuntu实用工具】—— Fcitx5 输入法安装与完整配置指南(新手友好+避坑版)
linux·数据库·ubuntu
kyle~2 小时前
MySQL基础知识点与常用SQL语句整理
android·sql·mysql
数据知道2 小时前
MongoDB 比较查询运算符:$gt, $lt, $ne, $in 在范围筛选中的实战应用
数据库·mongodb
德彪稳坐倒骑驴2 小时前
数仓中的数据建模方法
数据库·oracle
青衫码上行2 小时前
高频SQL 50题 | 聚合
数据库·sql·mysql·leetcode·面试