PostgreSQL。阅读解释计划

问题描述 投票:0回答:1

我正在运行Postgres 12。我有一个这样的解释计划。

Sort  (cost=87.71..88.75 rows=418 width=40)
  Sort Key: language.name DESC
  ->  Hash Join  (cost=1.14..69.51 rows=418 width=40)
        Hash Cond: (film.language_id = language.language_id)
        ->  Seq Scan on film  (cost=0.00..66.50 rows=418 width=21)
              Filter: (rating = ANY ('{R,PG-13}'::mpaa_rating[]))
        ->  Hash  (cost=1.06..1.06 rows=6 width=25)
              ->  Seq Scan on language  (cost=0.00..1.06 rows=6 width=25)

据我所知,启动成本等于0的节点将是最先运行的节点,所以这两个节点并行运行。

  • Seq Scan on film (cost=0. 00. 66. 50 rows=418 width=21)

  • 语言序列扫描(成本=0.00...1.06行=6宽=25)

那么这个节点就会被运行。Hash (cost=1. 06... 1. 06 rows=6 width=25).

然后这个节点。Hash Join (cost=1.14...69.51 rows=418 width=40)

最后是 排序(成本=87.71...88.75行=418宽=40)

然而,根据这个帖子。https:/thoughtbot.comlogreading-an-explain-analyze-query-plan。 执行顺序应该是

  • Seq Scan on language (cost=0.00...1.06 rows=6 width=25)

  • 哈希(成本=1.06...1.06行=6宽=25)

  • 胶片上的序列扫描(成本=0.00...66.50行=418宽=21)

  • 散列连接(成本=1.14...69.51行=418宽=40)

  • 排序(成本=87.71...88.75行=418宽=40)

那么哪个是正确的答案呢?我是否理解错了执行顺序?

postgresql sql-execution-plan
1个回答
0
投票

顺序如下。

  • 顺序扫描 language

  • 同时,根据结果建立一个哈希表(哈希表在完成之前不能使用,所以它的启动成本等于扫描的总成本)。

  • 顺序扫描 film

  • 同时,通过探测哈希表来计算哈希连接。

  • 一旦加入,就可以开始排序。


0
投票

据我了解,启动成本等于0的节点将是最先运行的节点。

这是不正确的。 启动成本是估计成本,直到它。提供 其第一行(直到它 接收 它的第一行)。) 它包括任何一个子节点的启动时间,但不包括任何一个非子节点的启动时间,即使它不能做任何工作,直到非子节点先做其他事情。

所以这2个节点是并行运行的。

你的计划并没有表现出任何并行行为 它们是互连的(我在化学上说的,我不知道是否有一个CS的术语),但不是并行的,因为在多个CPU上运行。

我认为你试图把它读得太多。 执行器的具体细节只与计划器的具体细节松散地联系在一起。

但对于执行器来说,它是这样的。

  • 开始对电影进行检索
  • 一旦它找到一个通过过滤的行,就暂停这个扫描,然后去做语言上的扫描完成,对结果进行哈希处理。
  • 假设哈希表适合内存,完成files中第一行的哈希连接,如果发现匹配,就把它送入排序,然后完成files中其余行与哈希表的匹配,也把它们送入排序。

每当有一行被送入排序,它就必须对其进行处理。 这可以是简单的插入缓冲区,也可以是将当前在缓冲区中的所有内容进行排序,然后全部写到磁盘上。

前两步之所以会出现奇怪的小舞蹈,是因为如果从 "电影 "中什么都找不到,就没有理由去读取和哈希 "语言"。 我认为规划师根本不承认这个舞蹈。

© www.soinside.com 2019 - 2024. All rights reserved.