【问题标题】:Creating a large number of entries in a SQL table efficiently高效地在 SQL 表中创建大量条目
【发布时间】:2013-07-07 23:33:40
【问题描述】:

我正在构建一个 RSS 阅读器,它会在阅读帖子时记录(就像 Google 阅读器所做的那样)。我让它在一定程度上工作,当我向下滚动时,它通过将行插入到“已读文章”表中来标记帖子为已读,该表记录了已读项目 (ciid)、阅读它的用户 (uid) 和阅读日期 (dateRead)。

现在,我正在考虑如何提供“全部标记为已读”功能。如果只有 25 篇未读文章,那就足够简单了。我将查询 25 篇文章的主文章表——我有一个子查询来确定哪些文章未​​读——当前用户未读,收集需要标记为已读的 ciids 并插入新的已读条目。但是,如果有 20,000 个条目未读怎么办?检索 20,000 个未读条目,收集那些 ciids 然后将 20,000 个插入命令发送回 MySQL 服务器似乎相当低效。

有没有更有效的方法来做到这一点,也许是使用直接处理所有这些的 SQL 查询?如果系统上只有一两个用户,我想我的低效方法不会有问题,但我希望系统能够相对较好地扩展。

【问题讨论】:

    标签: mysql subquery sql-insert


    【解决方案1】:

    你可以这样做

    REPLACE INTO read_articles (uid, dateread, ciid) 
    SELECT <user-id>, NOW(), id FROM articles
    

    您必须在其中指定要插入的用户 ID。 REPLACE INTO 将删除任何现有的日期读取。如果你不想要这种行为,你可以这样做

    INSERT INTO read_articles (uid, dateread, ciid) 
    SELECT <user-id>, NOW(), id FROM articles
    ON DUPLICATE KEY UPDATE uid=uid;
    

    但是,我认为您采用的方法(以每篇文章为基础存储已读文章)不可扩展。当用户单击全部标记时,您可以将该事件的日期时间存储在用户表中。所有早于最后标记日期的文章都被视为已读。

    也许您应该只考虑表格中过去 7 天的文章,即。定期删除超过一周的 read_articles 记录。所有超过 7 天的文章都被您忽略(所以实际上您假设它们已被阅读)。

    【讨论】:

    • 谢谢,@user1853955!这听起来像它会做的伎俩。我认为您对文章老化的看法是正确的——我需要考虑如何最好地实现这一点。我正在考虑完全从数据库中删除文章,假设它们已经到了一定的年龄,除非特定的 ciid 只有很少数量的文章。我不想将每个用户标记为“全部阅读”,因为用户可以标记提要,因此阅读全部可能仅适用于“技术”提要,而不适用于“国际新闻”提要。
    • 我想我可以为每个标签标记一个读取所有标志,尽管现在标签没有任何独立存在;它们只是作为不同提要的属性而存在。嗯……
    • 您可以存储每个用户已阅读的文章,可选择设置一些超时时间,而不会出现太多问题(假设索引正确)。问题是您的“全部阅读”功能会在此表中添加大量数据。我认为“最后一次阅读”日期(对于每个标签)是个好主意。
    • 这听起来很容易实现。感谢您的指点,@apartridge!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 2012-08-27
    • 1970-01-01
    • 2014-09-08
    • 2012-07-01
    • 2012-08-21
    相关资源
    最近更新 更多