SELECT DISTINCT(列)FROM索引列上的表的计算复杂性

时间:2013-08-22 18:09:05

标签: mysql sql group-by distinct time-complexity

问题

如果我混淆了这个术语,我就不是一个comp sci专业,所以请原谅我。调用

的计算复杂度是多少
 SELECT DISTINCT(column) FROM table

SELECT * FROM table GROUP BY column
在IS索引的列上?它是否与列中的行数或不同值的数量成比例。我相信这将是O(1)*NUM_DISINCT_COLS vs O(NUM_OF_ROWS)

背景

例如,如果我有1000万行但在该列中只有10个不同的值/组,您可以简单地计算每个组中的最后一项,这样时间复杂度将与不同组的数量相关联,而不是与行。因此,对于100万行,计算将花费与100相同的时间。我相信复杂性将是

O(1)*Number_Of_DISTINCT_ELEMENTS

但是在MySQL的情况下,如果我有10个不同的组,那么MySQL仍然会遍历每一行,基本上计算运行每个组的一些,或者它是以一组具有相同值的行的方式设置的可以在每个不同列值的O(1)时间内计算?如果没有,那么我相信它会意味着复杂性

O(NUM_ROWS)

我为什么关心?

我的网站中有一个页面,其中列出了消息类别的统计信息,例如总未读消息,总消息数等。我可以使用GROUP BYSUM()计算此信息,但我在随着消息数量的增长,这会花费更长时间,因此我会为每个类别提供统计信息表。发送或创建新消息时,我会增加total_messages字段。当我想查看状态页面时,我只需选择一行

SELECT total_unread_messages FROM stats WHERE category_id = x

而不是使用GROUP BY和/或DISINCT在所有邮件中实时计算这些统计信息。

在我的情况下,任何一种方式的性能都不是很大,所以这可能看起来像是“过早优化”的情况,但是知道什么时候我正在做一些关于或不可扩展的事情会很好其他选择不需要花费太多时间来构建。

1 个答案:

答案 0 :(得分:3)

如果你这样做:

select distinct column
from table

column上有一个索引,然后MySQL可以使用“松散索引扫描”处理此查询(描述为here)。

这应该允许引擎从索引读取一个键然后“跳转”到下一个键而不读取中间键(它们都是相同的)。这表明该操作不需要读取整个索引,因此通常小于O(n)(其中n =表中的行数)。

我怀疑找到下一个值只需要一个操作。如果整体复杂性类似于O(m * log(n)),其中m =不同值的数量,我不会感到惊讶。