应直接用 first() 或 find() 查单条数据,避免 where()->get()->first() 多查一次;whereIn 需分批并判空;selectRaw 聚合须 groupBy;with 预加载注意 N+1 和空关联访问。

直接用 where 查单条数据,别先 get() 再 first()
很多人写
$user = User::where('id', 1)->get()->first();,这会多查一次——get() 返回集合,再调 first() 取第一个。实际只要一条,直接用 first() 或 find():$user = User::where('id', 1)->first(); // 推荐
$user = User::find(1); // id 主键查询更简洁注意 find() 只支持主键(默认 id),传数组可查多条:User::find([1, 2, 3]); // 返回匹配的模型集合如果字段不是主键,比如查
email,必须用 where()->first()。
whereIn 和 whereNotIn 的数组长度限制与数据库兼容性
MySQL 默认对 IN 子句没有硬性上限,但过长(如上万 ID)会导致查询变慢甚至超时;PostgreSQL 对参数数量有限制(通常 65535)。Laravel 不会自动分批,你得自己控制:
$ids = [/* 几千个 ID */];另外,
foreach (array_chunk($ids, 1000) as $chunk) {
$users = User::whereIn('id', $chunk)->get();
// 处理 $users
}
whereIn 传空数组会生成 WHERE id IN (),MySQL 报错,PostgreSQL 返回空结果。务必提前判空:if ($ids) {
$users = User::whereIn('id', $ids)->get();
} else {
$users = collect(); // 空集合
}
用 selectRaw 做聚合或计算时,记得加 groupBy
比如统计每个城市的用户数:
User::selectRaw('city, count(*) as user_count')
->groupBy('city')
->get();漏掉 groupBy('city') 在 MySQL 5.7+ 严格模式下会报错:Expression #1 of SELECT list is not in GROUP BY clause。不同数据库行为不一致:SQLite 允许,PostgreSQL 强制要求。Laravel 不做 SQL 模式适配,你得按目标数据库规范写。另外,selectRaw 中的别名(如 user_count)不能在 where 或 orderBy 中直接用,得重复表达式或改用 having:->havingRaw('count(*) > 10')
with 预加载关联时,避免 N+1 和无效嵌套
查用户及其文章:
User::with('posts')->get();这是标准写法。但如果写成 User::with(['posts' => function ($q) {
$q->where('status', 'published');
}])->get();要注意:这个闭包只影响预加载的 posts 查询,不影响主查询;且若用户没文章,$user->posts 是空集合,不是 null。容易踩的坑是嵌套太深:User::with('posts.comments.user')->get();一旦某层关联数据为空(比如评论没用户),Laravel 不会报错,但后续访问 $comment->user->name 会触发 Trying to get property 'name' of non-object。建议用空合并:{{ $comment->user->name ?? '匿名' }}或者用 optional() 辅助函数。










