mysql、sql server、oracle 等中的 count、sum、avg 或任何其他内置“数学”函数的时间复杂度是多少?
有人会认为调用 sum(myColumn) 将是线性的。
但 count(1) 不是。实时复杂度是怎么来的?
在一个完美的世界中,我希望 sum、avg 和 count 为 O(1)。但我们不住在其中之一,对吗?
mysql、sql server、oracle 等中的 count、sum、avg 或任何其他内置“数学”函数的时间复杂度是多少?
有人会认为调用 sum(myColumn) 将是线性的。
但 count(1) 不是。实时复杂度是怎么来的?
在一个完美的世界中,我希望 sum、avg 和 count 为 O(1)。但我们不住在其中之一,对吗?
mysql、sql server、oracle 等中的 count、sum、avg 或任何其他内置“数学”函数的时间复杂度是多少?
在MySQL
with MyISAM
, COUNT(*)
without GROUP BY
is O(1)
(constant)
它存储在表元数据中。
在所有系统中,MAX
以及在没有are (对数)MIN
的索引表达式上。GROUP BY
O(log(n))
它们是通过单个索引查找来获取的。
聚合函数是O(n)
(线性的),当不使用GROUP BY
或GROUP BY
使用时HASH
聚合函数是O(n log(n))
when GROUP BY
uses SORT
。
所有值都应该被获取、计算并存储在状态变量中(可以存储在哈希表中)。
此外,在使用时SORT
,也应该进行排序。
在 SQL 中,聚合的数学函数复杂性完全无关紧要。唯一真正重要的是数据访问复杂性:选择什么访问路径(表扫描、索引范围扫描、索引查找等)以及读取了多少页。每个聚合的内部结构可能略有不同,但它们的工作方式几乎相同(保持运行状态并为每个输入值计算运行聚合),并且绝对没有聚合会查看输入两次,所以它们都是 O (n) 作为内部实现,其中“n”是提供给聚合的记录数(不一定是表中的记录数!)。
一些聚合具有内部快捷方式,例如。如果可能, COUNT(*)可能会从某些系统上的元数据返回计数。
注意:这是基于我对 SQL 查询计划器工作原理的理解的推测,可能并不完全准确。
我相信所有的聚合函数,或者至少是你上面提到的“数学”函数,应该是 O(n)。查询将大致执行如下:
但是请注意,即使聚合函数是 O(n),操作也可能不是。如果您创建一个笛卡尔将表连接到自身的查询,您将查看 O(n*n) 最小值以创建初始行集(步骤 #1)。排序以创建行组(步骤 #2)可能是 O(n lg n),并且可能需要磁盘存储来进行排序操作(与仅内存操作相反),因此如果您是操纵许多行。
对于大数据仓库式查询,主要数据库可以并行化任务,因此有多个 CPU 处理它。因此,由于协调并行线程的成本与使用多个 CPU 的好处相权衡,因此会有一些阈值点不是很线性。