目录
[二、建表时创建索引(CREATE TABLE)](#二、建表时创建索引(CREATE TABLE))
[1.普通索引(INDEX / KEY)](#1.普通索引(INDEX / KEY))
[2.唯一索引(UNIQUE INDEX)](#2.唯一索引(UNIQUE INDEX))
[3.主键索引(PRIMARY KEY)](#3.主键索引(PRIMARY KEY))
[三、表已经建好了:怎么添加索引?(ALTER TABLE)](#三、表已经建好了:怎么添加索引?(ALTER TABLE))
[四、另一套添加方式:CREATE INDEX(也很常见)](#四、另一套添加方式:CREATE INDEX(也很常见))
[五、删除索引(DROP INDEX)](#五、删除索引(DROP INDEX))
一、索引的创建语法(最核心)
MySQL 创建索引主要有两套写法:
✅ 建表时创建(CREATE TABLE)
✅ 表存在后添加(ALTER TABLE / CREATE INDEX)
二、建表时创建索引(CREATE TABLE)
1.普通索引(INDEX / KEY)
📌 语法:
sql
CREATE TABLE 表名 (
字段定义...,
INDEX 索引名(字段名)
);
✅ 示例:
sql
CREATE TABLE user (
id BIGINT PRIMARY KEY,
age INT,
INDEX idx_age(age)
);
📌 常见场景:
-
WHERE age = ? -
WHERE age > ? -
经常用来筛选/排序的字段
2.唯一索引(UNIQUE INDEX)
唯一索引的作用:保证某个字段的值不重复(比如邮箱、手机号)。
📌 语法:
sql
CREATE TABLE 表名 (
字段定义...,
UNIQUE INDEX 索引名(字段名)
);
✅ 示例:
sql
CREATE TABLE user (
id BIGINT PRIMARY KEY,
email VARCHAR(100),
UNIQUE INDEX uk_email(email)
);
📌 注意:
-
唯一索引会限制重复插入
-
插入重复值会报错(Duplicate entry)
3.主键索引(PRIMARY KEY)
主键索引的特点:唯一 + 非空,并且一张表只能有一个。
📌 语法:
sql
CREATE TABLE 表名 (
id BIGINT NOT NULL,
...,
PRIMARY KEY(id)
);
✅ 示例:
sql
CREATE TABLE user (
id BIGINT NOT NULL,
name VARCHAR(50),
PRIMARY KEY(id)
);
4.联合索引(多列索引)
联合索引就是:一个索引里放多个字段。
📌 语法:
sql
CREATE TABLE 表名 (
字段定义...,
INDEX 索引名(字段1, 字段2, 字段3)
);
✅ 示例:
sql
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT,
status TINYINT,
create_time DATETIME,
INDEX idx_user_status_time(user_id, status, create_time)
);
📌 常见场景:
- 查询某个用户的某种状态订单,并按时间排序
sql
SELECT * FROM orders
WHERE user_id = 1001 AND status = 1
ORDER BY create_time DESC;
5.全文索引(FULLTEXT)
全文索引用于文本检索,适合文章内容搜索。
📌 语法:
sql
CREATE TABLE 表名 (
字段定义...,
FULLTEXT INDEX 索引名(字段名)
);
✅ 示例:
sql
CREATE TABLE article (
id BIGINT PRIMARY KEY,
content TEXT,
FULLTEXT INDEX ft_content(content)
);
三、表已经建好了:怎么添加索引?(ALTER TABLE)
📌 在项目里最常用的就是这一套(上线后优化慢SQL)。
添加普通索引
sql
ALTER TABLE user ADD INDEX idx_age(age);
添加唯一索引
sql
ALTER TABLE user ADD UNIQUE INDEX uk_email(email);
添加联合索引
sql
ALTER TABLE orders ADD INDEX idx_user_status(user_id, status);
添加全文索引
sql
ALTER TABLE article ADD FULLTEXT INDEX ft_content(content);
📌 注意:
-
ALTER TABLE会修改表结构 -
大表加索引可能会比较慢(线上要小心)
四、另一套添加方式:CREATE INDEX(也很常见)
这个写法更"直观",专门用来创建索引。
创建普通索引
sql
CREATE INDEX idx_age ON user(age);
创建唯一索引
sql
CREATE UNIQUE INDEX uk_email ON user(email);
创建联合索引
sql
CREATE INDEX idx_user_status_time ON orders(user_id, status, create_time);
五、删除索引(DROP INDEX)
删除普通/唯一/联合索引
📌 语法:
sql
DROP INDEX 索引名 ON 表名;
✅ 示例:
sql
DROP INDEX idx_age ON user;
删除主键索引(特殊)
主键索引不是普通索引名,删除方式不同:
sql
ALTER TABLE user DROP PRIMARY KEY;
六、查看索引(排查必备)
查看表有哪些索引
sql
SHOW INDEX FROM user;
查看建表语句(索引也会显示)
sql
SHOW CREATE TABLE user;
查看建表语句(包含索引)
sql
SHOW CREATE TABLE user\G
📌 常见用途:
-
怀疑索引没建成功
-
想确认索引名字到底叫什么
-
看联合索引的字段顺序
七、不常见语法
前缀索引(适合长字符串)
如果字段很长(例如 email / url),可以只取前几个字符建索引节省空间。
sql
CREATE INDEX idx_email_prefix ON user(email(10));
📌 注意:
-
只索引前 10 个字符
-
区分度可能会下降(要看数据分布)
联合索引最左前缀(面试必考)
有索引:
sql
CREATE INDEX idx_a_b_c ON t(a, b, c);
能命中索引:
sql
WHERE a = 1
WHERE a = 1 AND b = 2
WHERE a = 1 AND b = 2 AND c = 3
❌ 不容易命中:
sql
WHERE b = 2
WHERE c = 3
WHERE b = 2 AND c = 3
一句话理解:联合索引要从最左列开始连续使用。
强制使用/忽略索引(排查慢SQL偶尔用)
强制使用:
sql
SELECT * FROM user FORCE INDEX(idx_age)
WHERE age = 18;
忽略索引:
sql
SELECT * FROM user IGNORE INDEX(idx_age)
WHERE age = 18;