先查EXPLAIN确认是否全表扫描(type: ALL),再优化;未走索引需立即建索引,复合查询等值字段在前、范围字段在后;with()非万能,深层嵌套宜用join或hasManyThrough;select必须显式指定字段;软删除字段deleted_at应建(deleted_at, id)覆盖索引;大数据分页用cursorPaginate()替代paginate()。
慢查询在 Laravel 里很少是 ORM 写错了,绝大多数时候是 SQL 没走索引、字段拉多了、关联没压平,或者分页方式错了——先查
,再动代码。
怎么确认是不是全表扫描(type: ALL)
别靠猜。在 Tinker 或临时路由里跑带参数绑定的
:
重点看
字段:
就是全表扫描;
或
才算健康。注意:
不带参数值,拼进去看执行计划容易误判。
如果
是
,立刻检查
字段有没有索引
复合条件如
,必须建联合索引,且等值字段(
)放前面、范围字段(
)放后面
这类函数操作会让索引失效,改用
with() 预加载为什么有时候更慢
不是银弹。它默认用多条
拼数据,一旦关联表没索引、主表数据多、或嵌套过深,就变成“把数据库压力转嫁给 PHP 内存和连接数”。
Laravel 13.2.0
PHP中文网提供Laravel 13.2.0版本下载,Laravel框架 是基于 PHP 8.3+ 的高性能框架,官方推荐通过 Composer 安装。它内置 AI SDK、JSON:API Resources 及原生向量搜索,支持属性驱动开发与队列路由,大幅提升开发效率。相比旧版,13.2.0 优化了缓存 TTL 管理与实时通信,无需 Redis 即可横向扩展。作为现代 Web 开发首选,它兼顾安全与极速体验,助您快速构建企业级应用。
下载
深层嵌套如
很可能触发笛卡尔积,行数爆炸
只查总数?用
,比
轻量得多
要“用户 + 最新一条帖子”,别写
——这会为每个用户跑一次子查询
真正要压平数据,优先考虑
+ 手动映射,或
select('*') 和不写 select() 一样危险
默认
或
等价于
,哪怕你只显示标题和时间。宽表+大结果集下,几十 KB 的冗余字段白走网络、白占内存、白耗 ORM 解析。
永远显式写
,不依赖
或模型定义
关联预加载也要约束字段:
API Resource 的
里删字段,只是序列化层补救;源头没控住,中间已浪费资源
软删除字段
没索引?全表扫描风险极高,建议建
覆盖索引
offset 分页在大数据量下为什么越来越卡
底层是
,偏移量越大,MySQL 越要扫过前 15000 行无用数据。十万级数据翻到第 100 页时,响应可能从 50ms 涨到 2s+。
换
,基于排序字段(如
或
)值跳跃定位,性能恒定
确保排序字段已建索引,且不能是随机值(如 UUID)——否则游标无效
前端必须原样传递上一页返回的
,不可手动构造或篡改
超大数据导出场景,
比
更稳(避免因删记录导致漏/重),但别在事务里用
最常被跳过的一步:没验证优化是否真生效。本地开
+
,或直接上
查「Queries」面板——N+1、重复查询、慢于 100ms 的语句,一眼就能揪出来。别让优化停留在“我以为”。
EXPLAINEXPLAINDB::select('EXPLAIN SELECT * FROM posts WHERE status = ? AND created_at > ?', [1, '2024-06-01']);typeALLrefrangetoSql()typeALLWHEREstatus = ? AND created_at > ?statuscreated_atwhereDate('created_at', ...)whereBetween('created_at', [$start, $end])with()SELECT ... WHERE id IN (...)with(['user.posts.comments.author'])withCount()with()with(['posts' => fn($q) => $q->latest()->limit(1)])join()hasManyThroughPost::get()Post::all()SELECT *select('id', 'title', 'user_id')$fillablewith(['user' => fn($q) => $q->select('id', 'name')])toArray()deleted_at(deleted_at, id)paginate()LIMIT 15 OFFSET 15000cursorPaginate()idcreated_atnext_cursorchunkById()chunk()DB::enableQueryLog()dd(DB::getQueryLog())Laravel Telescope