db() 默认每次新建连接导致性能差,db::name() 复用单例连接池;strict 模式可校验字段名避免静默失败;链式查询需复用基础对象并慎用终结方法。

直接用 db() 做链式查询,性能容易掉坑里——它默认每次调用都新建数据库连接,不是单例。
db() 助手函数为什么比 Db::name() 慢
每次调用 db('user'),底层都会执行一次 Db::connect(),哪怕配置完全一样。而 Db::name('user') 或 Db::table('user') 复用的是单例连接池里的 Connection 实例。
- 频繁在循环里写
db('log')->where(...)->insert(),等于每轮都连一次库 - 想复用连接?必须显式传第三个参数
false:db('user', [], false) - 若需动态切换数据库配置(比如读写分离),
db()的第二个参数可传数组,但依然要加false才能避免重复连接
where() 条件写错字段名却不报错?开 strict 模式
默认情况下,where('non_exist_field', 1) 不会报错,只会让 SQL 查不到数据——因为字段名校验被关了。
- 开启严格模式:
Db::name('user')->strict(true)->where('non_exist_field', 1)->select(),立刻抛出SQLSTATE[42S22]: Column not found - 全局开启:在数据库配置里加
'strict' => true - 注意:连表查询时,
strict只校验主表字段,关联表字段不检查
链式操作中途想复用,别急着 select()
select()、find()、delete() 这些终结方法一调就执行 SQL 并清空内部条件缓存,没法再链了。
- 构造基础查询对象:
$base = Db::name('user')->where('status', 1)->where('deleted_at', null) - 后续分支复用:
$admins = $base->where('role', 'admin')->select(),$members = $base->where('level', 'vip')->select() - 调试看生成的 SQL:
$base->buildSql()返回带?占位符的字符串,不会执行 - 别在 foreach 里反复写
Db::name('user')->where(...),复用$base对象更轻量
order() 传数组没生效,先确认字段在不在当前表
order(['sort' => 'asc', 'id' => 'desc']) 看似没问题,但一旦用了 join 或视图,字段可能来自不同表,MySQL 会静默忽略。
- 查字段归属:
Db::getTableInfo('user', 'fields')确认sort确实在主表 - 连表时明确指定表别名:
order('u.sort asc, u.id desc')(假设主表 alias 为u) - 字符串形式更可控:
order('FIELD(status, 3, 2, 1)')这种 MySQL 特有函数,必须用字符串传,数组不支持
真正容易被忽略的是:链式操作对象本身是无状态的,但 db() 的连接行为、strict 的开关位置、以及 buildSql() 返回的占位符字符串——这些细节不验证,线上查半天慢查询,可能就卡在这三处。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











