背景
“你们怎么给亿级用户表加索引的?线上直接执行ALTER TABLE?”
90%的程序员会犯的致命错误:
❌ 在业务高峰时段硬上弓
❌ 以为INPLACE算法绝对安全
❌ 没配置innodb_online_alter_log_max_size
去年双十一前夕,某酒店商旅平台核心支付表突发死锁,直接导致支付链路瘫痪30分钟。
复盘发现:运维同学在晚高峰给1.2亿行大表加索引,触发全局锁等待。
你以为的加索引:
ALTER TABLE user ADD INDEX idx_phone (phone); -- 轻轻松松3秒完成
实际生产环境的可能加索引:

如何判断什么时候可以给大表加索引?
随着业务的快速发展,像 user
这样的用户表数据量不断增加,可能你已经注意到查询速度变慢了,尤其是某些 SQL 变成了“慢查询”。
这时,你想通过加索引来提升查询性能。但别急,给大表加索引可不是轻松事,一不小心可能会让数据库“崩溃”。
因为索引的创建是DDL(数据定义语言)操作,它有可能导致锁表,阻塞其他操作,影响业务。
所以,怎样才能安全地给大表加索引?这就得好好了解一下。
两种索引构建方式
MySQL 在构建索引时,有两种方式:在线模式和离线模式。
- 在线模式(Online DDL):
这种方式可以在构建索引的同时,数据库仍然可以进行读写操作,对业务的影响较小。但不是所有数据库版本和存储引擎都支持这个模式。比如,如果你的 MySQL 是 InnoDB 存储引擎的较新版本,可以通过一些设置启用在线模式。不过在线模式会消耗更多的系统资源,这点要注意。 - 离线模式(Offline DDL):
这种方式在构建索引时会锁住表,不能进行任何读写操作,直到索引创建完成。虽然这种方式操作简单直接,但会对业务造成比较大的影响,适用于可以停机的场景。如果你的数据库能忍受一定的停机时间,或者是在业务低峰期加索引,离线模式也是一个选择。
DDL 和 DML 小知识
先给大家补充下基础知识:
- DDL(数据定义语言):主要用来定义或修改数据库结构,比如创建、删除表,创建或删除索引等操作。
- DML(数据操作语言):主要用来操作数据库中的数据,像插入(INSERT)、更新(UPDATE)和删除(DELETE)这些操作。
索引属于 DDL 操作,它是对数据库结构的修改,所以需要特别小心。