题
我不是计算机科学专业的学生,如果混淆了术语,请原谅我.调用的计算复杂度是多少
SELECT DISTINCT(column) FROM table
要么
SELECT * FROM table GROUP BY column
在被索引的列上?它与行数或列中不同值的数目成正比.我相信那将是O(1)* NUM_DISINCT_COLS与O(NUM_OF_ROWS)
背景
例如,如果我有1000万行,但在该列中只有10个不同的值/组,那么您可以直观地计算每个组中的最后一项,因此时间复杂度将与不同组的数量而不是行数相关.因此,计算100万行所需的时间与进行100行相同的时间.
O(1)*Number_Of_DISTINCT_ELEMENTS
但是在MySQL的情况下,如果我有10个不同的组,MySQL仍会遍历每一行,基本上是计算每个组的运行,还是以可以计算相同值的一组行的方式进行设置在O(1)时间中每个不同的列值?如果没有,那么我相信这意味着复杂性
O(NUM_ROWS)
我为什么在乎?
我的网站上有一个页面,其中列出了消息类别的统计信息,例如未读总数,消息总数等.我可以使用GROUP BY和SUM()来计算此信息,但我觉得这将花费更长的时间消息的增长,所以我有一个针对每个类别的统计信息表.发送或创建新消息时,我增加了total_messages字段.当我想查看状态页面时,我只需选择一行
SELECT total_unread_messages FROM stats WHERE category_id = x
而不是使用GROUP BY和/或DISINCT计算所有邮件中的统计信息.
对我而言,这两种方式的性能影响都不大,因此这似乎是“过早优化”的一种情况,但是很高兴知道我何时在做关于其他选项可扩展或不可扩展的事情不需要很多时间来构建.
解决方法:
如果您正在做:
select distinct column
from table
并且列上有一个索引,然后MySQL可以使用“松散索引扫描”(描述为here)来处理该查询.
这应该允许引擎从索引中读取一个键,然后“跳转”到下一个键,而无需读取中间键(它们都是相同的).这表明该操作不需要读取整个索引,因此通常小于O(n)(其中n =表中的行数).
我怀疑找到下一个值仅需要一个操作.如果整体复杂度类似于O(m * log(n)),其中m =不同值的数量,我不会感到惊讶.