发布于2026-07-10 阅读(0)
扫一扫,手机访问
加索引不等于查询变快,关键要加在WHERE、JOIN、ORDER BY、GROUP BY高频字段(如user_id、status、created_at),外键和softDeletes字段需手动加索引;联合索引须按最左匹配原则设计顺序;字符串字段须控制前缀长度(如->length(191));必须用EXPLAIN验证索引是否生效。

直接加索引不等于查询变快,关键得加对地方、用对方式。Lara vel 迁移里写 $table->index('user_id') 很容易,但线上慢查没解决,大概率是索引没命中、顺序错了,或者字段本身不适合建索引。
经常碰到的情况:SELECT * FROM orders WHERE user_id = 123 执行要 2 秒,EXPLAIN 显示 type: ALL(全表扫描);或者分页查 WHERE status = 'shipped' ORDER BY created_at DESC 卡顿,却只给 status 加了单列索引。
WHERE、JOIN ON、ORDER BY、GROUP BY 中的列,比如 user_id、status、created_atuser_id)几乎必须加索引 —— Lara vel 的 foreignId() 不会自动加,得手动补 ->index()softDeletes() 字段(deleted_at)如果常用于筛选(如 whereNull('deleted_at')),也建议加索引常见错误:建了 ['status', 'created_at'] 索引,但查询是 WHERE created_at > '2025-01-01' AND status = 'paid',EXPLAIN 显示没走索引;或者 ORDER BY created_at DESC 没生效,还是 Using filesort。
user_id),范围查询或排序字段放后面(如 created_at)$table->index(['user_id', 'created_at'], 'orders_user_created_idx') → 支持 WHERE user_id = ?、WHERE user_id = ? ORDER BY created_at$table->index(['created_at', 'user_id']) → WHERE user_id = ? 基本不走索引这个问题很隐蔽:本地开发加了 $table->string('description')->index(),上线后 EXPLAIN 发现没用上;或者迁移报错 Specified key was too long。
utf8mb4,VARCHAR(255) 实际最多占 1020 字节,而 MySQL InnoDB 单索引默认上限是 767 字节(老版本)或 3072 字节(5.7+ 启用 innodb_large_prefix)$table->string('description', 500)->index()->length(191)$table->index('email', 'users_email_idx'),否则 Lara vel 自动生成的名字(如 users_email_index)在多环境删索引时容易混淆fullText() 仅适用于 MySQL MyISAM 或 InnoDB(8.0+),且需确保引擎和字符集支持另一个容易踩的坑:用 whereJsonContains('meta->tags', 'lara vel') 查得很慢,EXPLAIN 显示全表扫描;或者迁移里直接写 $table->index('meta') 报错。
$table->json('meta'); $table->string('meta_status')->virtualAs("JSON_UNQUOTE(JSON_EXTRACT(`meta`, '$.status'))")->index();DB::statement("CREATE INDEX idx_users_meta_name ON users((JSON_EXTRACT(meta, '$.name')));")DB::statement() 手动执行最常被忽略的一点:加完索引不验证是否真被用上。别只看迁移跑成功了,一定要在生产库上用 EXPLAIN 对照真实查询语句跑一遍,尤其关注 key、rows、Extra 字段。索引不是加得越多越好,写入变慢、空间浪费、优化器选错索引,都是真实代价。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8