我正在尝试优化一个查询,这个查询(不必要地)在一个表中计算将近90万行,这花费了太长的时间。
该表包含发生在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
在本例中,我的当前查询如下所示:
选择log_type,从my_logs中将(*)计数为未读,其中is_read=0 GROUP BY log_type;
该查询对每一行进行计数,并给出每种日志类型的正确行数。 问题是,当表包含90万行时,这是一个昂贵的查询,每种类型的行数超过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_type
集合在一起,并将其限制为1001行,这不是我想要的。 我需要将行拆分为每个log_type
,然后计算最多1001行。 在本例中,我想要的输出是:
log_type unread
'Type 1' 3
'Type 2' 2
这道题和这道题讨论了当找到n行时如何停止计数,但不要考虑到我需要的分组。
有人知道解决办法吗?
这个答案在MariaDB或MySQL中不起作用。
你要找的答案是基于一个“侧向表表达式”。 这是在Oracle,DB2,PostgreSQL和SQL Server中实现的。
以下是PostgreSQL中从表中读取行的最佳查询:
select x.log_type, count(y.z)
from (
select distinct log_type as log_type
from my_log
) x
left join lateral (
select 1 as z
from my_log b
where b.log_type = x.log_type and is_read = 0
limit 2 + 1
) y on true
group by x.log_type
参见DB Fiddle中的运行示例。
横向查询根据放在它们前面的表表达式上的可用值执行一次。 在本例中,表表达式x
将为log_type
生成所有不同的值(使用索引来实现性能)。 然后横向查询将针对x
中的每个值执行一次,限制
为3(在本例中)。 最后,查询会计算遇到多少z
值。
如您所见,上面的进程最多只读取每个类型的3行。
返回数组中的每个第 n 个元素。 使用 Array.filter() 创建一个包含给定数组的每个第 n 个元素的新数组。 const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1); everyNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ]
问题内容: 所以我查了一下,这个问题非常相似,但是它缺少一个关键点:SQL Server计算表的每一列中不同值的数量 因此,在这个问题中,他们希望每列的计数都不同。我想要做的是获取表中每个列的每个不同值的计数(而我正在为特定数据库中的所有表执行此操作,这就是为什么我要尝试尽可能地自动化这一点的原因尽可能)。当前,我的代码看起来像这样,我必须为每一列运行: 理想情况下,我的输出应如下所示: 以此类推
问题内容: 我有一个简单的表,像这样: 我想获得每个用户出现的前2个“字母”, 甚至更好:崩溃成列 我怎样才能在postgres中做到这一点? 问题答案: = > SQL小提琴演示
问题内容: 我有一张表格,我想获取每个组的最新条目。这是桌子: 桌子 该表将按降序分组并按降序排序。对于每个,我想获取最新状态。 我的首选输出: 是否有任何汇总函数只能从每个组中获得最高排名?请参阅下面的伪代码: DocumentID, GetOnlyTheTop(Status), GetOnlyTheTop(DateCreated) FROM DocumentStatusLogs GROUP B
问题内容: 我如何能够在oracle查询中为几个组获得N个结果。 例如,给定下表: 有更多行和更多职业。我想从每个职业中聘请三名员工(可以说)。 有没有不用子查询就可以做到这一点的方法? 问题答案: 这将产生所需的内容,并且不使用供应商特定的SQL功能(例如TOP N或RANK())。 在此示例中,它为三位雇员提供每个职业emp_id最低的值。您可以更改不等式比较中使用的属性,以使其按名称或其他方
问题内容: 以下是最简单的示例,尽管任何解决方案都应能够扩展到需要n个顶级结果的地方: 给定下面的表格,其中包含“人员”,“组”和“年龄”列,您将如何 获得每个组中 年龄 最大的2个人? (组内的关系不应产生更多结果,而应按字母顺序给出前两个) 所需的结果集: 注意: 这个问题建立在先前的问题上- 获取每组分组的SQL结果的最大值的记录 -用于从每组中获取一个顶行,并且从@Bohemian那里收到
问题内容: 有什么方法可以计算数组中每个项目的出现? 可以说我有: 这里的输出将是: 如果我有: 输出为: 这里的输出只是为了展示预期的结果。 问题答案: 你可以使用来自Google Collections / Guava的或来自Apache Commons的。 如果你有一个集合而不是一个数组,则可以用于addAll()将整个内容添加到上述数据结构中,然后将该方法应用于每个值。一个或会给你以定义的
有没有一种方法可以简化或使R代码更优雅?