【问题标题】:How to optimize retrieval of most occurring values (hundreds of millions of rows)如何优化最常出现的值的检索(数亿行)
【发布时间】:2011-11-12 04:39:10
【问题描述】:

我正在尝试从包含数亿行的 SQLite 表中检索一些最常出现的值。

到目前为止的查询可能如下所示:

SELECT value, COUNT(value) AS count FROM table GROUP BY value ORDER BY count DESC LIMIT 10

value 字段上有一个索引。

但是,使用 ORDER BY 子句,查询需要很长时间,我从未见过它的结尾。

可以做些什么来大幅改进对如此大量数据的此类查询?
我尝试添加 HAVING 子句(例如:HAVING count > 100000)来减少要排序的行数,但没有成功。

请注意,我不太关心插入所需的时间(它仍然需要合理,但优先考虑选择),所以我愿意接受建议在插入时进行计算的解决方案.. .

提前致谢,

【问题讨论】:

  • Java 在哪里发挥作用?
  • 以防万一解决方案包括后/预处理,这是我用来与数据库交互的语言。
  • 您正在开发什么类型的应用程序?

标签: java sql sqlite optimization query-optimization


【解决方案1】:

1) 创建一个新表,您将在其中存储每个唯一“值”和“计数”一行,在计数列上放置一个降序索引
2) 将触发器添加到原始表,您可以根据需要维护这个新表(插入和更新)以增加/减少计数。
3) 在这个新表上运行你的查询,由于递减计数索引,它将运行得很快

【讨论】:

  • 我试过这个解决方案,问题是,插入现在需要很长时间。我正在批量插入大约 300K 行(使用附加数据库中的 SELECT INSERT),没有触发器,这在几秒钟内完成,使用触发器,插入空表需要几个小时跨度>
  • 我建议提出一个新问题,在其中提供两个表模式、触发器代码并询问如何加快触发器速度。
  • 我会接受这个答案,感谢您提出 DESC INDEX。看来使用触发器毕竟不是一个好主意,但我想我应该更详细地解释我正在做的事情:)
【解决方案2】:

此查询强制您查看表中的每一行。这需要时间。

我几乎从不推荐这样做,但在这种情况下,您可以在外部表中以非规范化方式维护计数。

在插入、更新和删除期间通过触发器将值和计数放入另一个表中。

【讨论】:

    猜你喜欢
    • 2012-10-13
    • 2012-04-06
    • 1970-01-01
    • 2019-08-23
    • 2021-12-12
    • 1970-01-01
    • 2013-08-17
    • 2022-10-02
    • 2011-10-17
    相关资源
    最近更新 更多