mysql主键索引与二级索引区别_mysql索引结构设计优选
主键索引即聚簇索引,数据行直接存储在B+树叶子节点中,查询时无需回表;二级索引仅存索引列和主键值,需回表获取完整行记录。主键索引就是聚簇索引,数据行直接存里面MySQL 的 InnoDB 引擎里,PRIMARY KEY 索引不是“普通索引加个唯一约束”那么简单——它决定了整张表数据的物理存储顺序。也就是说,SELECT * FROM t WHERE id = 123 这种查询,InnoDB 找到 id = 123 对应的 B+ 树叶子节点时,**那一页里就直接躺着完整的行记录**,不用二次回表。常见错误现象:EXPLAIN 显示 type=const 但 Extra 里还带 Using where,其实是没走对主键,或者字段类型隐式转换导致索引失效。主键必须非空且唯一,不能是 NULL如果建表时没显式定义 PRIMARY KEY,InnoDB 会悄悄选一个 NOT NULL UNIQUE 列当主键;都找不到,就自动生成隐藏的 row_id(6 字节),但这会让 SELECT * FROM t 结果不可预测主键越短越好,比如用 BIGINT 代替 VARCHAR(36) 做主键,B+ 树层级更少,范围扫描更快二级索引只存「索引列 + 主键值」,查数据要回表所有非主键的 INDEX(包括 UNIQUE INDEX、FULLTEXT、SPATIAL)都是二级索引。它的 B+ 树叶子节点不存整行数据,只存索引字段值和对应记录的主键值(比如 name 索引里存的是 ('Alice', 105),其中 105 是主键 ID)。使用场景:当你执行 SELECT name FROM user WHERE name = 'Alice',能直接从二级索引里拿到结果(覆盖索引);但一旦写成 SELECT email FROM user WHERE name = 'Alice',就得拿着 105 再去主键索引里捞一遍完整行——这就是“回表”,IO 开销翻倍。联合二级索引要注意最左前缀:INDEX (a, b, c) 能加速 WHERE a=1 AND b=2,但对 WHERE b=2 无效如果业务经常查 SELECT a,b,c FROM t WHERE x=1,与其让优化器回表,不如建覆盖索引 INDEX (x, a, b, c)二级索引本身也占空间,INSERT/UPDATE 时要同时维护主键树和所有二级索引树,索引越多写越慢为什么 ORDER BY 有时走不了索引排序是否能复用索引,关键看「索引顺序」和「查询条件+排序字段」是否构成连续的最左前缀。比如有联合索引 INDEX (status, create_time): 通义听悟 阿里云通义听悟是聚焦音视频内容的工作学习AI助手,依托大模型,帮助用户记录、整理和分析音视频内容,体验用大模型做音视频笔记、整理会议记录。
