MySQL查看表索引

MySQL查看表索引

引言

排查慢查询、判断索引是否生效前,先要搞清楚一张表上到底建了哪些索引、每个索引包含哪些列、是不是唯一索引。SHOW INDEX和information_schema都能查,前者直观,后者适合脚本批量统计。

SHOW INDEX查看索引

SHOW INDEX FROM users;

列出users表全部索引,Key_name是索引名,Column_name是索引列,Seq_in_index是列在联合索引里的顺序,Non_unique为0表示唯一索引。

重点字段含义

  • Key_name:索引名,PRIMARY是主键;
  • Seq_in_index:联合索引中的列顺序,最左前缀从这里判断;
  • Column_name:该索引包含的列;
  • Non_unique:0唯一,1普通;
  • Sub_part:前缀索引长度;
  • Cardinality:基数,越接近总行数区分度越好。

建表语句里看索引

SHOW CREATE TABLE users\G

直接看完整建表语句,KEY和UNIQUE KEY就是索引定义,适合快速人工核对。

information_schema批量查

SELECT table_name, index_name, column_name, seq_in_index, non_unique
FROM information_schema.statistics
WHERE table_schema = 'mydb'
ORDER BY table_name, index_name, seq_in_index;

一次性导出整库所有表的索引结构,做索引巡检和冗余分析。

查某列是否被索引覆盖

SELECT DISTINCT index_name FROM information_schema.statistics
WHERE table_schema='mydb' AND table_name='users' AND column_name='phone';

判断phone列有没有索引,决定查询能否走索引。

注意事项

  • 联合索引顺序决定最左前缀,别只看有没有建;
  • Cardinality是估算值,会随ANALYZE TABLE刷新;
  • 前缀索引Sub_part只索引前N个字符;
  • 重复冗余索引用pt-duplicate-key-checker之类工具清理;
  • 索引不是越多越好,写多表要权衡插入成本;
  • 查完索引再配合EXPLAIN看实际是否命中。

总结

SHOW INDEX FROM表看索引明细,SHOW CREATE TABLE看定义,information_schema.statistics批量导出整库索引。重点关注索引名、列顺序、唯一性和基数,联合索引按最左前缀使用,建完索引务必用EXPLAIN验证是否真正命中,定期清理重复冗余索引,避免写放大。


emer 发布于  2026-10-20 07:06 

MySQL唯一索引创建

MySQL唯一索引创建

引言

邮箱、手机号、订单号这类业务字段要求不能重复,光靠应用层判断并发下仍可能插入重复值。唯一索引在数据库层直接约束重复,是防脏数据的最后一道保险,同时还能加速等值查询。

建表时定义唯一索引

CREATE TABLE users (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL,
    email VARCHAR(100) NOT NULL,
    UNIQUE KEY uk_email (email)
);

uk_email是索引名,email列唯一。

已有表追加唯一索引

ALTER TABLE users ADD UNIQUE KEY uk_phone (phone);

数据里已有重复值时会报错1062,需先清理重复再加。

组合唯一索引

多列组合唯一,比如同一商品同一活动只领一次券:

ALTER TABLE coupon ADD UNIQUE KEY uk_user_goods (user_id, goods_id);

允许单列重复,但组合起来不能重复。

插入重复的报错处理

INSERT INTO users(email) VALUES('a@x.com');
-- 再次插入同email触发 1062 Duplicate entry

应用层catch错误码,返回邮箱已注册,而不是让500报错。

插入或更新冲突

INSERT INTO users(email) VALUES('a@x.com')
ON DUPLICATE KEY UPDATE login_time=NOW();

唯一键冲突时转成更新,适合登录时间刷新。

注意事项

  • 加唯一索引前先查重:SELECT email,COUNT(*) FROM users GROUP BY email HAVING COUNT(*)>1;
  • NULL在唯一索引里可以出现多个,MySQL不认为NULL相等;
  • 唯一索引也是普通索引,等值查询能走索引;
  • 大表加索引会锁表或耗时,高峰期用在线DDL;
  • 删除索引DROP INDEX uk_email ON users。

总结

唯一索引在建表时用UNIQUE KEY定义,已有表用ALTER TABLE ADD UNIQUE KEY追加,多列组合唯一用组合索引。加之前先清重复,插入冲突用ON DUPLICATE KEY UPDATE转更新,数据库层约束比应用层判断更可靠。


emer 发布于  2026-10-19 07:28 

MySQL索引设计原则

MySQL索引设计原则

引言

MySQL索引相当于书籍目录,快速定位数据,避免全表扫描。不合理的索引不仅无法提升查询速度,还会降低写入性能。索引设计是数据库优化最基础、最高效的手段,建站、接口开发都需要掌握。

索引核心原理

InnoDB引擎索引基于B+树实现,主键索引叶子节点存储完整行数据;二级索引叶子节点存储主键值,查询会触发回表。索引字段越大,占用磁盘越多,内存缓存能存放的索引越少,查询越慢。

索引设计核心原则

  1. 选择性优先:优先给区分度高的字段建索引,如手机号、ID;性别、状态这类只有少量枚举值字段不适合单独建索引。
  2. 联合索引遵循最左匹配原则,字段顺序:等值查询在前,范围查询放后面。
  3. 避免在索引字段做函数运算,where YEAR(create_time)=2026会直接失效索引。
  4. 不要过度建索引,每次新增、更新、删除数据,所有索引都需要同步更新,拖累写入。

示例SQL

-- 联合索引示例,适合 where uid=100 and create_time>xxx
CREATE INDEX idx_uid_ct ON user(uid,create_time);

-- 查看sql是否命中索引
EXPLAIN SELECT * FROM user WHERE uid=100;

常见踩坑

  • 字符串字段不加引号,隐式类型转换,索引失效;
  • 模糊查询%关键词,前置百分号不走索引;
  • 联合索引跳过左侧字段,无法触发索引。

总结

索引不是越多越好,按需创建。建索引前先用explain分析执行计划,优先优化高频查询SQL,控制索引数量,平衡查询与写入性能。


emer 发布于  2026-10-18 07:10 
'); })();