APP首页显示100篇文章,每篇文章显示最新3条评论。要求速度最快,效率最优,大家平常怎么解决的?

问题描述

最近一直思考这个问题,项目数据都是百万级别的,百度了很多方案,貌似没有最好的方案

1:循环查库肯定不行了
2:链表查询(行吗)?
3:laravel ORM 模型(行吗)?貌似也是取所有评论数据,然后take切断

不知道子查询行不行,外层查询100篇文章,子查询最新3条评论,然后CONCAT_WS或者GROUP_WS连接评论

928 12 0
12个回答

Dalong

Db::table('table')->limit(100)->select();

不行吗

ysxpark

作缓存定时更新吧

nitron

百万级能有多大,就算用1最坏情况也就是1+100个查询,DB索引和缓存得当这都不是问题

  • PHP甩JAVA一条街 2023-04-23

    哈哈, 上个项目, 才几个月600w条了

  • nitron 2023-04-23

    基础消耗是摆在那里(假定单条查询全都走了索引),就算你怎么个去考虑如何写,最终的基础消耗都差不多,与其在这个地方扣细节(我看你已经纠结了好多天了),不如在其他的地方考虑如何去降低使用基础消耗的频次(比如缓存)

    换我就想都不用想直接第一种+缓存简单直接,别看它土但是有效啊,花时间琢磨些奇技淫巧最后发现浪费了时间却没卵用..

    你这个是文章,不是高频交易,实时性没有那么重要
    laravel ORM 伪代码

    $atricles = db::table('article')->where(xxx)->orderby(xxx)->->limit(100)->get()->each(function($item){
        $tiem->comments = db::table('comments')->where(xxx)->orderby(xxx)->->limit(3)->get();
    });
    
  • PHP甩JAVA一条街 2023-04-23

    循环查库啊

  • nitron 2023-04-24

    是啊,有什么问题么?

  • nitron 2023-04-25

    不要觉得我这个土,主表38个字段,2500万数据,关联表41个字段,6600万数据,都走索引的情况下,用上面的方式执行时间100ms左右

不败少龙

laravel ORM 中的with去查询评论呢?

小W

1.App一次性无法显示100条,可以做成滚动加载模式
2.异步加载每条的评论

关键看数据库表设计,以及app产品的设计。

muyu

sql或者orm层面没有什么好的方案,可以如果是mysql8,可以使用窗口函数row_number和over试试,但是缓存是最佳的方案

brookeov
with(['comments' => function($query){
    $query->limit(3);
}])
  • 暂无评论
ab0029

使用Laravel ORM如下

$articles = Article::limit(100)->get();
$query = $articles->map(
    fn($query) => $query->comments()->limit(3)
)->reduce(
    fn($carry, $query) => $carry ? $carry->unionAll($query) : $query
);

$comments = $query->get();
  • ab0029 2023-04-24

    手动拼接成union all 语句,然后一条去sql去数据库查询,其他条件自己拼接即可

这多明显,app显示满根本显示不了100条,你这做个分页,下拉加载就行了

  • 暂无评论
mon

不考虑反查最新评论,获取300条最新评论的还有关联的文章记录,在用PHP整合一下就完事了么?[狗头]

  • 暂无评论
缝合

首先,需要在文章表和评论表之间建立一对多的关联关系,即在评论表中引入一列文章 id(article_id),表示评论所属的文章。

假设文章表名为 article,具有 article_id、title、content 等列;评论表名为 comment,具有 comment_id、article_id、content 等列。

然后,使用以下 SQL 语句来查询文章和对应的最新3条评论:

SELECT a.title, a.content, c.content
FROM 
    (SELECT article_id, title, content FROM article LIMIT 100) a 
    LEFT JOIN 
    (
        SELECT article_id, content 
        FROM comment c1 
        WHERE (
            SELECT COUNT(*) 
            FROM comment c2 
            WHERE c2.article_id = c1.article_id AND c2.comment_id >= c1.comment_id
        ) <= 3
    ) c ON a.article_id = c.article_id 
ORDER BY a.article_id DESC, c.comment_id ASC

首先,使用子查询获取最新发布的100篇文章,限制显示数量不超过100篇,以提高查询效率。
然后,使用左连接将文章和评论合并起来,并使用子查询获取每篇文章的最新3条评论。
最后,按照文章 id 降序排列,评论 id 升序排列,确保结果集中的评论是最新的前三条。
需要注意的是,以上 SQL 语句仅供参考,具体实现还需要针对实际情况进行调整和优化。同时,还需要注意索引和缓存的使用以提高查询效率。

  • 暂无评论
请叫我邹先生

查询出文章然后循环拼接查询评论的sql union all

如:

( SELECT id,article_id, content FROM comment where id =1 limit 3)
union all
( SELECT id,article_id, content FROM comment where id =2 limit 3)
  • 暂无评论
年代过于久远,无法发表回答
🔝