【问题标题】:How can I efficiently identify the most popular strings in a large table?如何有效地识别大表中最流行的字符串?
【发布时间】:2011-09-30 21:38:42
【问题描述】:

假设一个包含 5000 万个姓氏的表格(例如),如何有效地识别前 10000 个姓氏?

还有比这更有效的查询吗?

SELECT count(last_name) as cnt, last_name
FROM last_name_table
GROUP BY last_name
ORDER BY cnt DESC
LIMIT 10000;

假设:

CREATE TABLE last_name_table (
    `last_name` VARCHAR(255), 
     KEY `last_name` (`last_name`)
);

我可以在 20 分钟内获得前 1000 名。但是前 10000 名需要一整天(字面意思)。有什么建议吗?

【问题讨论】:

  • 我目前卡在“复制到磁盘上的 tmp 表”。

标签: mysql optimization performance query-optimization


【解决方案1】:

如何有效地识别大表中最流行的字符串?

根据您的问题,我假设您不需要确切的数字,近似数字就足够了。

我让您选择随机行的子集并对其进行所有需要的计算。然后对结果进行相对缩放以获得反映整个表格的近似结果。即使使用近似值,您也有足够多的数据来获得准确的结果。

【讨论】:

    【解决方案2】:

    建议:预先计算每个last_name的计数,并将其存储在单独的表中。

    使用触发器维护它(如果在 last_name_table 中每分钟没有数千次插入,或者如果实时统计有意义)或每天一次(小时等)调度程序。

    【讨论】:

      【解决方案3】:

      SQL92 为此定义了一个“TOP”运算符,因此在符合 SQL92 的数据库中您应该能够编写
      SELECT TOP 10000 ... FROM last_name_table;

      但是 MySQL 没有实现这一点,您必须根据自己的建议使用 LIMIT。

      【讨论】:

      • 问题是关于使查询高效。自豪地 - 看不到任何可以提高查询性能的建议。
      【解决方案4】:

      如果您添加一个子句“HAVING count(last_name) > 10”或类似的内容,那么它将从您的结果中删除所有不常见的项目。这样做,您将不需要“限制”或“订购依据”。它可能会加快速度。此外,如果您使用 last_name 字段对 cnt 进行索引,则该索引可能会提高性能。

      【讨论】:

        猜你喜欢
        • 2021-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-05
        • 2015-04-30
        • 2011-09-12
        • 1970-01-01
        相关资源
        最近更新 更多