【问题标题】:MySQL - Complexity of: SELECT COUNT(*) FROM MyTable;MySQL - 复杂性:SELECT COUNT(*) FROM MyTable;
【发布时间】:2011-03-10 09:55:53
【问题描述】:

这个 MySQL 查询的复杂度是多少

SELECT COUNT(*) FROM MyTable;

表中的条目数是否存储在某处并在每次插入或删除行时更新?如果是这样,那么复杂度应该是 O(1)。

【问题讨论】:

  • 在您添加WHERE 声明的那一刻,它似乎必须是O(N),因此请谨慎评估。

标签: mysql sql database


【解决方案1】:

这取决于存储引擎。

  • 对于 MyISAM,为每个表存储总行数,因此SELECT COUNT(*) FROM yourtable 是一个 O(1) 操作。它只需要读取这个值。
  • 对于 InnoDB,不存储总行数,因此需要进行全面扫描。这是一个 O(n) 操作。

来自manual

InnoDB 不保留表中的内部行数。 (实际上,由于多版本控制,这会有些复杂。)要处理SELECT COUNT(*) FROM t 语句,InnoDB 必须扫描表的索引,如果索引不完全在缓冲池中,则需要一些时间。如果您的表不经常更改,使用 MySQL 查询缓存是一个很好的解决方案。要获得快速计数,您必须使用您自己创建的计数器表,并让您的应用程序根据它所做的插入和删除来更新它。 SHOW TABLE STATUS 也可以在近似行数足够的情况下使用。请参阅第 13.2.13.1 节,“InnoDB Performance Tuning Tips”。

【讨论】:

  • 我有一个问题。如果按照复杂度,我们指的是磁盘读取的次数,是否仍然是O(n) 来扫描表的索引?不取决于索引类型吗?
【解决方案2】:

MyISAM 中的 AFAIK 行数被缓存,在 InnoDB 中没有,并且每次计数时,他都会计算所有行。

【讨论】:

    【解决方案3】:

    我不确定该值是否已存储,但这对您的查询一点也不重要。 将 MySQL 与您的查询一起使用,它将在您执行它的那一刻计算所有返回的行。

    【讨论】:

    • 重要与否,这是他的决定,不是吗?对我来说,这似乎是一个非常有效的问题。
    • 了解函数的复杂性非常重要,尤其是避免长查询,当您拥有大量数据时执行更智能的查询。
    猜你喜欢
    • 2012-12-11
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    相关资源
    最近更新 更多