2016-02-29 43 views
1

我在MySQL查询看起来是这样的:流量execution- MySQL的

SELECT *, min(start_date_time) as min_start_date_time 
    FROM result_table 
    where part_number= '101' 
    group by part_serial; 

我期待查询将组的结果通过part_serial然后将创建一个新列“min_start_date_time”具有最小START_DATE_TIME在每一行中,对于给定的part_serial。

但我得到的是,每个部分串行只有1行,其中start_date_time是给定串行的最小值。

有人可以解释此查询的执行流程吗?

+2

'by part_serial'按'part_serial'值创建一个组。你得到的结果是每组一行。 –

+1

请提供样品数据和预期结果。这将帮助我们弄清楚你正在努力完成什么。 – sgeddes

+0

*“对于给定的part_serial,每行中的最小start_date_time”*听起来就像*“对于每个部分序列1行,其中start_date_time是给定序列的最小值”* – JNevill

回答

0

除了为集合函数计算创建边界之外,这听起来像是您期望GROUP BY子句更像是ORDER BY子句,只是强迫组中的行在结果中彼此相邻。不是这种情况。 GROUP BY子句实际上将结果集过滤为每个组一行。

有人可以解释执行的流程此查询

我将它取刺,但请记住,这是一个非常简化流程。除此之外,获取更复杂的内容并不多,数据库可以使用统计信息和索引来更改此基本查询流,当查询引擎认为它可以生成更快或更高效的计划时。我也不能把它留给这个查询,因为解释流程流程时没有给JOIN提供至少一点提示,并且其他复杂性会产生一些误导性的解释。这个免责声明,让我们开始吧。

该过程从规划阶段开始,以识别表空间。也就是说,数据库计算FROM子句使用的表以及任何JOIN中的表或视图的匹配规则。它实际上并没有将这些内容加载到内存中,除了可能是记录指针或主键。现在它只是计算表的匹配规则,并确定完成连接和生成结果行的最有效方法。

作为一个例子,您可以连接到一个有5列的表,其中连接条件与第三列中的外键匹配,但表的主键是第一列,而选择列表最终只使用来自第四栏。在这个阶段,数据库只是构建计划,以最快的方式为每个记录加载原始表的第四列数据。可能有一个索引,其中可以使用第3列和第4列来满足查询,也可能需要通过第1列中的主键从原始表中加载数据。做出这种决定就是这里涉及的内容。

对于像这个问题一样的单表查询,所有这些通常只是确定查询是否可以完全从索引满足的问题,但它仍然是该过程的重要部分。

完成后,数据库开始检查查询的主/原始表中的每一行。对于每一行,它将首先应用WHERE子句的相关部分(希望能够充分利用索引),从而使工作集保持较小。然后它为任何匹配上一步中确定的规则的连接表提取数据。它会应用WHERE子句的任何剩余元素,因为这样做...再次保持查询的内存和磁盘使用尽可能低,并尽可能快地释放不必要的信息。

有时,当某个联接与目标表中的多个记录相匹配时,此过程将实现新行,但该过程将持续到计算始发行的整个结果为止。

由于每个物化行都已完成,因此可以应用GROUP BY子句。这通过查看该行并识别该行所属的组来确定。此时,行被合并(不复制)成新的工作集(如果没有GROUP BY子句,可以跳过该行)。如果新集合已经有一个匹配组的行,那么它只更新任何聚合函数计算(为该组添加1 COUNT,检查是否有新的MAX或MIN,更新SUM,最终允许进行AVG计算等)。如果新组尚未具有该组的行,则将使用当前行的种子数据在该组中创建一行。当数据库完成原始集合中的行时,它们可以被丢弃。一旦整个GROUP BY子句完成,查询不再需要原始工作集。

此时,可以评估HAVING子句(如果有)以及ORDER BY子句。

最后,数据库启动流结果到客户端应用程序。由于每一行都是流式处理,因此SELECT子句指定的任何转换都将执行并包含在最终结果集中。