【发布时间】:2020-10-01 02:29:28
【问题描述】:
我正在尝试优化一个查询(不必要地)计算表中近 900 000 行的查询,这需要的时间太长。
该表包含发生在 Web 应用程序不同部分的事件的日志条目,我想知道当该类型的行数为 1000 或更少时,每种日志类型存在多少未读日志条目,但计数为如果计数为 1001 或更多,则最多为 1001 行。
之后我不需要再数了,我会为该日志类型输出“超过 1000 个”。
假设我们有一个名为my_logs 的带有数据的表:
id log_type log_text is_read
1 'Type 1' 'Text 1' 1
2 'Type 1' 'Text 2' 1
3 'Type 1' 'Text 3' 0
4 'Type 1' 'Text 4' 0
5 'Type 1' 'Text 5' 0
6 'Type 1' 'Text 6' 0
7 'Type 2' 'Text 7' 0
8 'Type 2' 'Text 8' 0
在本例中,我当前的查询如下所示:
SELECT log_type, COUNT(*) AS unread FROM my_logs WHERE is_read = 0 GROUP BY log_type;
此查询计算每一行,并为每种日志类型提供正确的行数。问题是当表包含 900 000 行时,这是一个昂贵的查询,并且完全没有必要计算每种类型超过 1000 行,因为用户不会关心 1 000 和 20 000 之间的差异,他们只会查看很多条目。
这是我最接近的解决方案(调整限制以适应 my_logs 示例并演示用法):
SELECT log_type, COUNT(*) AS unread
FROM (
SELECT log_type
FROM my_logs ml1
WHERE is_read = 0
LIMIT 3 /* To display "more than 2" in webapp */
) AS ml2
GROUP BY logtype_txt;
但是这个查询将内部查询中的所有log_types 汇集在一起,并将 that 限制为 1001 行,这不是我想要的。我需要将行拆分为每个 log_type,然后 然后 计算最多 1001 行。在这个例子中我想要的输出是:
log_type unread
'Type 1' 3
'Type 2' 2
This question 和 this question 讨论如何在找到 n 行时停止计数,但不要考虑我需要的分组。
有人知道解决办法吗?
【问题讨论】:
-
澄清问题:您是否需要从您拥有的每种日志类型中仅获取 1000 个未读日志条目?你有多少种日志类型?
-
我什至不需要日志条目;我只需要 count 每种日志类型有多少未读日志条目,并且我想在每种日志类型找到 1001 个条目时停止计数(一种日志类型可以有 514 个条目,而另一种则停止计数为 1001)。日志类型可以是我们突然决定使用的任何字符串,因此日志类型的数量是动态的。