ThinkPHP高性能开发关键在于精准控制:批量导入禁用冗余事务,日志调至error级,缓存按场景选用,SQL必须可见可控;Db::insertAll()本身原子高效,显式事务仅用于跨表一致性场景;单次批量200–1000条需依字段复杂度调整;务必关闭app_debug并用fetchSql()验证实际SQL。

ThinkPHP 高性能开发不是靠堆配置或换框架,而是对几个关键动作的克制与精准控制:批量操作不加事务、日志关到最低、缓存用对地方、SQL 看得见摸得着。
Db::insertAll() 不要套 Db::transaction()
纯数据导入场景下手动加事务只会拖慢速度,因为 Db::insertAll() 本身已是一条带多组 VALUES 的原子 SQL,MySQL 隐式事务足够可靠。加了 Db::transaction() 反而延长锁持有时间,在并发写入时容易触发锁等待甚至超时。
只有两类情况才需要显式事务:
- 插入同时要更新另一张表(比如写订单 + 扣库存)
- 这批数据必须和其它业务操作构成一致性单元(如创建用户 + 分配初始角色)
Excel 导入、日志归档、后台批量补数?跳过 transaction(),直插更稳。
立即学习“PHP免费学习笔记(深入)”;
单次 insertAll() 控制在 200–1000 条之间
数量不是越多越好,max_allowed_packet 和 PHP 内存会卡住你。超限报错是 Packets larger than max_allowed_packet are not allowed,不是语法错误,容易误判。
安全建议按字段复杂度调整:
- 5 个字段以内(如
id,name,status):单次 500–1000 条 - 10+ 字段(含
created_at,updated_at,remark):压到 200–300 条 - 含
TEXT或JSON类型字段:别超 100 条
别依赖 saveAll() 替代——它会逐条调用模型的 save(),触发验证、事件、自动时间戳,1000 条可能比 insertAll() 慢 3–5 倍。
上线前必须关掉 app_debug 和日志写入
app_debug = true 时,Db::insertAll() 每次都会把完整 SQL 和参数写进日志文件,IO 直接拉满。本地跑 1w 条卡死?八成是日志在狂刷磁盘。
临时提速可加一行:
Log::close();
但根本解法是确保生产环境 app_debug 为 false,且日志级别设为 error 或更低。调试模式开着,ORM 就会做一堆无用 trace,性能损耗肉眼可见。
用 fetchSql() 看清 ORM 实际生成的 SQL
ThinkPHP 的 where()->select() 看似简单,但嵌套关联、with()、scope() 容易生成低效 SQL。不看真实语句,优化就是盲猜。
加 ->fetchSql(true) 能直接返回 SQL 字符串,不用执行:
User::where('status', 1)->with('profile')->fetchSql(true);
重点检查:
- 是否出现 N+1 查询(多个相同主表 + 不同子表查询)
- WHERE 条件有没有走索引(
EXPLAIN一下) - JOIN 是否必要,能否改用 IN 子查询或应用层组装
ORM 是工具,不是黑盒。SQL 不可控,性能就不可控。



















