这个 SQL 查询应该怎么写提高效率?
有以下三张表:
- users (用户表)
id name
- columns (分类表)
id title
- articles (文章表)
id title column_id
他们的关联关系是:一个用户可以关注多个分类,一个分类可以用多篇文章
我简单一下化需求:
查询十篇文章,必须是用户已经订阅的分类中的。(假设关联都已经设置好)// 查询已经关注的分类 $subscribe_columns = AUth::user()->columns()->select('id')->get()->pluck('id'); $articles = Article::whereIn('column_id', $subscribe_columns)->paginate(10);
加入我关注了一千个分类,一万个分类。这样子会感觉效率有问题,是否有更高的查询构造方法?或者这种情况压根不应该用
whereIn
效率慢的问题已经解决,原因是框架自带的分页,自己写分页就快了,用框架的分页 3.5 s,自己写 300ms
尝试使用 Article::whereIn('column', $subscribe_columns)->paginate(10) 来分页, 看会不会有所改善..如果还有其他的关联数据在页面中使用的话,最好先用with预加载
@刘滔 我一开始就是使用框架自带的分页,想简单说明一下问题才写成那样的,已修改。 现在已经知道是框架自带的分页使查询速度变慢了。 使用 offset()->limit() 来弄了分页
请问是如何测试速度的,我刚学不久,在做个人博客
ORM很好用,但是很多性能问题都是ORM框架引起的,不是所有的项目都适合用ORM框架
paginate()用的不就是offset() limit()吗? 问题应该出现在count()上吧
@lalalalalaTwoEyes 我用的 postman 可以直接捉取时间的。
@YuxiangDong 谢谢 :+1:
@klgd 里面应该有更复杂的计算,也许是我的前面条件太多影响到了。一个计算 count 应该影响没有这么大
可以使用类似 select * from articles where column in ( select id from columns
联查user - columns中间表
),这样可以省去多余的传输。我也在做一个类似的需求,不过我那个还要复杂一点,还涉及到了关注的人什么的,还有各种多态模型。其实这些东西从数据库考虑本身就有问题,如果量级达到你所说的会有某个用户关注上千上万的话,你数据库怎么查也撑不住,肯定要从缓存等各方面入手。hasMany
@dividez
hasMany
+ 预加载$subscribe_columns = AUth::user()->columns()->pluck('id')->toArray();
$articles = Article::whereIn('column_id', $subscribe_columns)->paginate(10);
@Abel94 我那个查询构造器转成 SQL, 应该和你的那个差不多吧。
@dividez 我直接这样获取 ID ,不会更快吗?
@MehrLicht 哈哈,这个差不多,不纠结。
@DavidNineRoc 我想说的是可能toArray()会好点;我直接发现过一个问题,不将对象转换成数组,部分情况下会出现性能问题
@lalalalalaTwoEyes DB::getQueryLog();