【问题标题】:Best approach to select most viewed posts from last n hours从过去 n 小时中选择查看次数最多的帖子的最佳方法
【发布时间】:2016-11-04 22:47:51
【问题描述】:

我正在使用 PHP 和 MYSQL(innodb 引擎)。

正如 MYSQL 参考所说,通过比较一列进行选择并按另一列排序不能使用我们考虑的索引。

我有一个名为 News 的表。

此表至少有 100 万条记录,其中包含两个重要列:time_addednumber_of_views

我需要从最近的n 小时中选择查看次数最多的记录。执行此操作的最佳索引是什么?或者是否可以对具有数百万条记录的表非常快速地运行这种查询?

我已经为“最后一天”做了这个,这意味着我可以通过添加一个新列 (date_added) 来选择前一天查看次数最多的记录。但是如果我决定选择上周的这些记录,我又遇到了麻烦。

【问题讨论】:

  • 您应该提供要在问题中使用的查询。

标签: php mysql indexing innodb


【解决方案1】:

首先,编写查询:

select n.*
from news n
where time_added >= date_sub(now(), interval <n> hours)
order by number_of_views desc
limit ??;

最好的索引是(time_added, number_of_views)。实际上,number_of_views 不会用于完整查询,但我会将其包含在其他可能的查询中。

【讨论】:

    【解决方案2】:

    首先,您必须将以下行添加到 my.cnf(在

    部分中
    [mysqld]):
    query_cache_size = 32M (or more).
    query_cache_limit = 32M (or more)
    

    query_cache_size设置缓存大小

    另一个需要注意的选项——这个query_cache_limit——它设置了查询结果的最大数量,可以放在缓存中。 查看缓存状态,可以请求如下:

    show global status like 'Qcache%';
    

    http://dev.mysql.com/doc/refman/5.7/en/mysql-indexes.html

    如果表有一个多列索引,优化器可以使用索引的任何最左边的前缀来查找行。例如,如果您在 (col1, col2, col3) 上有一个三列索引,则您在 (col1)、(col1, col2) 和 (col1, col2, col3) 上有索引搜索功能。欲了解更多信息,请参阅http://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html

    【讨论】:

    • "视图经常发生,对吗?每次更新表时,该表的查询缓存中的 所有 条目都会被删除。这使得 QC 对您的任务。您可能最好关闭它。
    【解决方案3】:

    您需要一个汇总表。由于“小时”是您的粒度,因此可能会这样:

    CREATE TABLE HourlyViews (
        the_hour DATETIME NOT NULL,
        ct SMALLINT UNSIGNED NOT NULL,
        PRIMARY KEY(the_hour)
    ) ENGINE=InnoDB;
    

    如果您计数的项目有一些细分,它可能需要另一列(并将其添加到 PK 中)。您可能希望在此表中添加一些其他的 SUM'd 或 COUNT'd。

    逐步构建和维护此表。也就是说,每小时向表中添加另一行。 (或者您可以使用INSERT .. ON DUPLICATE KEY UPDATE .. 保持更新。)

    More on Summary Tables

    然后更改查询以使用该表;会快很多

    【讨论】:

      猜你喜欢
      • 2020-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-06
      • 2010-09-26
      • 2017-04-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多