诸如 count、sum、avg 或 mysql、sql server、oracle 等中的任何其他内置“数学”函数的函数的时间复杂度是多少?

人们可能会认为调用 sum(myColumn) 是线性的。

但 count(1) 不是。真正的时间复杂度是怎么来的?

在完美的世界中,我希望 sum、avg 和 count 为 O(1)。但我们并不生活在其中之一,不是吗?

有帮助吗?

解决方案

在SQL聚集体的算术运算功能的复杂性是完全irelevant。真正重要的唯一的事情是数据acceess复杂性:选择什么样的访问路径(表扫描,索引范围扫描,索引查找等),以及还有多少页被读取。有可能是在每个聚集的内部细微的差别,但他们所有的工作几乎相同的方式(保持运行状态和计算每个输入值运行聚集),而且是绝对的 NO 的聚集,着眼于输入的两倍,因此它们所有的O(n)作为内部实现,其中“n”是供给到聚合recordes的数目(未necesarily记录在表!数)。

一些聚集体具有内部快捷方式,例如。 COUNT(*)返回从元数据中的计数在某些系统中,如果可能的。

其他提示

诸如 count、sum、avg 或 mysql、sql server、oracle 等中的任何其他内置“数学”函数的函数的时间复杂度是多少?

  • MySQLMyISAM, COUNT(*) 没有 GROUP BYO(1) (持续的)

    它存储在表元数据中。

  • 在所有系统中, MAXMIN 在没有索引的表达式上 GROUP BYO(log(n)) (对数)。

    它们通过单个索引查找来获取。

  • 聚合函数是 O(n) (线性),当不使用时 GROUP BY 或者 GROUP BY 用途 HASH

  • 聚合函数是 O(n log(n)) 什么时候 GROUP BY 用途 SORT.

所有值都应该被获取、计算并存储在状态变量中(可以存储在哈希表中)。

另外,当使用 SORT, ,它们也应该被排序。

笔记:这是基于我对 SQL 查询规划器如何工作的理解的推测,可能并不完全准确。

我相信所有聚合函数,或者至少是您上面提到的“数学”函数,都应该是 O(n)。该查询将大致执行如下:

  1. 获取与连接谓词和过滤谓词匹配的行(即“WHERE 子句”)
  2. 根据 GROUP BY 子句创建行组。为没有 GROUP BY 的查询创建单个行组
  3. 对于每个行组,将聚合函数应用于组中的行。对于 SUM、AVG、MIN、MAX 以及 CONCAT 等非数字函数,有简单的 O(n) 算法,我怀疑使用了这些算法。为步骤 #2 中创建的每个行组在输出集中创建一行
  4. 如果存在 HAVING 谓词,则使用此谓词过滤输出行

但请注意,即使聚合函数的复杂度是 O(n),操作也可能不是。如果您创建一个笛卡尔将表与其自身连接的查询,则您将需要 O(n*n) 最小值来创建初始行集(步骤#1)。排序以创建行组(步骤 #2)可能是 O(n lg n),并且可能需要磁盘存储来进行排序操作(而不是仅在内存中操作),因此如果您操作许多行。

有关大数据仓库风格的查询,主要的数据库可以并行的任务,所以有多个CPU上工作。因此会有阈点在那里并不像的成本线性统筹并行线程折衷对使用多个CPU的益处。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top