MIN / MAX函数如何在SQL中运行?

时间:2018-02-10 13:53:58

标签: sql oracle

我正在尝试理解MIN / MAX函数如何计算sql中支持的值

假设我有下表Duplicate

ID  NAME
1   A
2   A
3   A
4   A
5   A
6   B
7   B
8   B
9   B
10  B
11  C
12  C
13  C
14  C

当我运行以下查询时

SELECT MAX(ID), NAME FROM Duplicate
  GROUP BY NAME

sql引擎是否在每个组中找到ID的第一个MAX值,然后从那些Grouped记录中找到MAX ID?这是正确的还是其他事情发生了?

2 个答案:

答案 0 :(得分:2)

你会在Oracle中看到类似的内容

SQL> set autotrace traceonly explain
SQL> select owner, max(object_id)
  2  from   t
  3  group by owner;

Execution Plan
----------------------------------------------------------
Plan hash value: 47235625

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      |    37 |   407 |   431   (2)| 00:00:01 |
|   1 |  HASH GROUP BY     |      |    37 |   407 |   431   (2)| 00:00:01 |
|   2 |   TABLE ACCESS FULL| T    | 78939 |   847K|   427   (1)| 00:00:01 |
---------------------------------------------------------------------------

“按哈希分组”。这是一种机制,通过它我们可以避免大量的分类成本来执行聚合(最小值,最大值等)。

概念上它是这样的:

  • 阅读第一行
  • 按列散列小组(在我的情况下为“所有者”)
  • 让我们说哈希值是1234.
  • 将“object_id”的值存储在存储桶1234中。

然后

  • 阅读下一行
  • 按列散列小组(在我的情况下为“所有者”)
  • 让我们说哈希值是5678.
  • 将“object_id”的值存储在存储桶5678中。

然后

  • 阅读下一行
  • 按列散列小组(在我的情况下为“所有者”)
  • 让我们说哈希值是1234(即,相同的值是第1行)。
  • 将object_id值与存储桶5678中的现有object_id进行比较。如果它更大,则替换它,否则忽略并继续。

因此,您可以看到我们可以识别最大值而无需排序 - 只需对所有数据进行一次扫描。

答案 1 :(得分:0)

我不知道你正在使用什么数据库,但是对于以并行方式分配表行的Teradata,使用GROUP BY的简单聚合通常会这样做:

  1. 汇总行(本地)
  2. 重新分配行
  3. 排序行
  4. 汇总行(全局)
  5. 返回最终结果
  6. 您使用的是什么DBMS?您可以在查询上运行EXPLAIN以查看查询计划是什么吗?这会给你一些想法。