跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Laravel查询优化怎么做_Laravel慢查询优化【技巧】

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

相关文章