Laravel中两种用户消息查询方式的性能对比及预加载性能影响咨询
嘿,刚接触Laravel和SQL就能留意到这两种查询方式的差异,已经很到位啦!我来给你把这两个问题讲明白:
两种用户消息查询方式的性能对比
先从底层执行的SQL来看两者的区别:
Message::where('user_id', auth()->user()->id)->get():这条语句会直接触发1次数据库查询,对应的SQL是SELECT * FROM messages WHERE user_id = ?(?替换为当前登录用户的ID),一步到位拿到所有目标消息。auth()->user()->messages:这里要分两种场景:- 如果当前请求中还没加载过用户模型(比如刚进入请求,还没调用过
auth()->user()),那么会先执行1次用户查询(SELECT * FROM users WHERE id = ?),再执行1次消息查询,总共2次数据库请求。 - 但如果用户模型已经在请求里被加载过了(比如中间件已经获取过当前用户,或者之前的代码调用过
auth()->user()),那只会触发1次消息查询,和第一种方式的性能几乎无差别。
- 如果当前请求中还没加载过用户模型(比如刚进入请求,还没调用过
结论
从性能角度,首次获取用户时第一种方式少一次查询,略占优势;但从代码可读性和Eloquent的设计语义来看,auth()->user()->messages更贴合模型关联的逻辑,代码更简洁优雅。日常开发中,两种方式都可以用,看场景选择就行。
关于预加载的性能误解
你朋友的说法完全搞反啦!预加载(Eager Loading)其实是解决N+1查询性能问题的核心方案,不仅不会拖慢性能,反而能大幅提升查询效率。
举个典型的N+1场景:假设你要遍历10个用户,然后逐个获取他们的消息。如果不用预加载,会先执行1次查询拿到10个用户,然后每个用户都触发1次消息查询,总共1+10=11次数据库请求——这对数据库的压力会随着用户数量增加而直线上升。
但如果用预加载:User::with('messages')->get(),只会执行2次SQL:
- 一次查询获取所有目标用户
- 一次查询用
IN条件获取这些用户的所有消息
直接把查询次数从11降到2,性能提升非常明显。
那什么时候预加载可能“看起来”影响性能?只有当你预加载了大量用不上的关联关系,或者关联的数据量极大却没有做筛选时,才会出现冗余数据的问题,但这是使用方式的问题,不是预加载本身的锅。正确使用预加载,只会让你的数据库查询更高效。
内容的提问来源于stack exchange,提问作者Ryan Garde
相关产品推荐
相关产品推荐

