来源丨经授权转自 捡田螺的小男孩(ID:gh_3d11c9893ca0)
作者丨捡田螺的小男孩
前言
大家好,我是捡田螺的小男孩~
日常开发中,我们后端程序员经常需要写SQL。写完SQL后,我们会考虑对查询条件的列加索引。
那么,你知道mysql中,一个表最多只能加多少个索引嘛?一个联合索引最多只能多少列呢?索引加多了,会存在哪些问题呢?
最近有位星球粉丝说,去阿里面试,就问了这么一道面试题~~ 田螺哥按照自己的思路来回答一波:
1. InnoDB存储引擎
根据MySQL官方文档,索引数量的核心限制与存储引擎相关的,我们先来看InnoDB存储引擎。
它最多允许 64个二级索引(即非主键索引),官方文档有说明的哈,绝非空穴来风~
https://dev.mysql.com/doc/refman/8.0/en/innodb-limits.html
我们在设计表的时候,要设计一个主键的,也就是一个主键索引。
因此,InnoDB中,一个表,最多可以有 64+1=65 个索引
而对于单个索引,最多支持多少列呢? 最多是16,官方文档也是有说明的:
2. MyISAM存储引擎
而对于MyISAM存储引擎来说,一个表最多是64个索引,主键索引是不计入此限制滴~
一个索引最多包含16列,官方文档也是有说明的
https://dev.mysql.com/doc/refman/8.0/en/myisam-storage-engine.html
有些开发者混淆了“单个索引的列数限制”与“总索引数限制”。例如,单个联合索引最多16列(如 INDEX (col1, col2, ..., col16)),而非总索引数量。
3. 一个表设计多少个索引合理呢?
索引是一种能提高数据库查询效率的数据结构。它可以比作一本字典的目录,可以帮你快速找到对应的记录。
正所谓水能载舟,也能覆舟。适当的索引能提高查询效率,过多的索引会影响数据库表的插入和更新功能。
有些时候,不加索引更合适:
当然,大多数情况,都是要加索引的~~ 日常开发中,一个表设计多少个索引合适呢?
阿里巴巴《Java开发手册》技术文档,单表索引数量建议控制在5个以内
当然,5个只是经验值而非绝对限制吧。之前看过我们业务表,很多都有6、7个的。如果你一个表超过8个,可能真的是表设计不太合理了。
4. 索引设计过多存在哪些问题?
尽管MySQL,InnoDB存储引擎,允许最多65个索引,但实际开发中我们一般建议不超过5个索引。索引过多会引发以下问题:
每次数据插入、更新或删除时,所有相关索引都需要同步维护。例如,一张表有30个索引,更新一行数据可能需要修改30个B+树结构,导致事务延迟和锁竞争加剧。
每个索引单独存储一份数据副本。以百万级数据表为例,10个索引可能占用数GB额外空间,加剧磁盘压力。
MySQL优化器需评估所有可能的索引路径,索引过多会延长执行计划生成时间。极端情况下,优化器可能选择非最优索引,反而降低查询效率。
备份、迁移、表结构变更等操作会因索引过多变得缓慢。例如,ALTER TABLE 添加字段时,需重建所有索引,耗时可能从秒级增至小时级。