应在where、join、order by、group by中频繁使用的字段(如user_id、status、created_at)及外键、softdeletes字段加索引;字符串字段需控制前缀长度;联合索引注意字段顺序;生产环境应避免直接迁移加索引,推荐pt-online-schema-change等工具。

什么时候该在 Laravel 迁移里加索引
不是所有字段都值得加索引,加错反而拖慢写入、浪费空间。真正需要索引的,是那些频繁出现在 WHERE、JOIN、ORDER BY 或 GROUP BY 中的字段——比如 user_id、status、created_at。
常见错误现象:查 orders 表按 user_id 查单个用户订单很慢,但迁移里没给 user_id 加索引;或者用 where status = 'paid' order by created_at desc 分页卡顿,却只给 status 加了单列索引,没考虑联合查询场景。
- 外键字段(如
user_id)几乎总是要加索引,Laravel 的foreignId()不会自动加,得手动补->index() -
softDeletes()字段(deleted_at)如果常用于筛选(如“查未删除的商品”),建议加索引 - 字符串字段加索引前先确认长度,MySQL 对
VARCHAR(255)默认只索引前 768 字节,可能失效,要用->index('name', 'name_index')并配合->length(191)控制前缀长度
Laravel 迁移中加索引的写法差异
写法看着差不多,但底层 SQL 和效果差别挺大。关键看你是想建普通索引、唯一索引,还是联合索引,以及是否要指定索引名——名字不写清楚,后期删索引或查问题时容易懵。
- 单字段普通索引:
$table->index('email');→ 生成随机名(如users_email_index),可读性还行 - 显式命名索引(推荐):
$table->index('email', 'users_email_idx');→ 后续用dropIndex('users_email_idx')更稳妥,尤其在多环境同步时 - 联合索引必须用数组:
$table->index(['user_id', 'status'], 'orders_user_status_idx');—— 顺序很重要,WHERE user_id = ? AND status = ?能命中,反过来就可能走不完索引 - 唯一索引别只写
->unique(),它默认建唯一约束,不是纯索引;真要唯一 + 索引,用->unique('email')即可,Laravel 会同时建唯一索引
加索引时最容易被忽略的兼容性坑
本地跑得通,上线报错,大概率是 MySQL 版本或引擎不一致。InnoDB 对索引长度、字符集、前缀限制比你想象中严格。
- MySQL 5.7+ 默认
innodb_large_prefix=ON,但老项目可能关着;如果字段是utf8mb4(Laravel 9+ 默认),VARCHAR(255)实际占 1020 字节,超 InnoDB 单索引 767 字节上限 → 必须加前缀:$table->string('description')->index()->length(191); - SQLite 在测试时不会报索引长度错,但部署到 MySQL 就挂,所以本地开发尽量用和生产一致的 DB 驱动
- PostgreSQL 不支持索引前缀,
->length()在 pgsql 下会被忽略,但也不会报错——这意味着你在 pgsql 上以为加了索引,其实没生效,查起来照样慢
线上加索引为什么卡住?怎么安全操作
直接在大表上跑 php artisan migrate 加索引,很可能锁表几分钟甚至更久,用户请求全堵住。这不是 Laravel 的锅,是数据库 DDL 的天然限制。
- MySQL 5.6+ 支持
ALGORITHM=INPLACE,但仅限某些操作;加索引基本都支持,但你要确认执行的是ADD INDEX而不是重建表(比如改字段类型就不是) - 生产环境务必加
--force前先手工验证:SHOW CREATE TABLE users;看当前结构,再用EXPLAIN ALTER TABLE users ADD INDEX idx_email (email);(MySQL 8.0.12+)预估影响 - 更稳妥的做法是用
pt-online-schema-change(Percona Toolkit)或 Laravel 的DB::unprepared()手动分步执行,但前提是 DBA 允许并配好权限
最常被绕开的一点:索引不是加得越多越好。一个表超过 5 个索引,写入性能下降会明显,而且优化器选错索引的概率上升。上线前用 EXPLAIN SELECT ... 对照加索引前后的执行计划,才是真验证。











