我正在运行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)
那么哪个是正确的答案呢?我是否理解错了执行顺序?
顺序如下。
顺序扫描 language
同时,根据结果建立一个哈希表(哈希表在完成之前不能使用,所以它的启动成本等于扫描的总成本)。
顺序扫描 film
同时,通过探测哈希表来计算哈希连接。
一旦加入,就可以开始排序。
据我了解,启动成本等于0的节点将是最先运行的节点。
这是不正确的。 启动成本是估计成本,直到它。提供 其第一行(直到它 接收 它的第一行)。) 它包括任何一个子节点的启动时间,但不包括任何一个非子节点的启动时间,即使它不能做任何工作,直到非子节点先做其他事情。
所以这2个节点是并行运行的。
你的计划并没有表现出任何并行行为 它们是互连的(我在化学上说的,我不知道是否有一个CS的术语),但不是并行的,因为在多个CPU上运行。
我认为你试图把它读得太多。 执行器的具体细节只与计划器的具体细节松散地联系在一起。
但对于执行器来说,它是这样的。
每当有一行被送入排序,它就必须对其进行处理。 这可以是简单的插入缓冲区,也可以是将当前在缓冲区中的所有内容进行排序,然后全部写到磁盘上。
前两步之所以会出现奇怪的小舞蹈,是因为如果从 "电影 "中什么都找不到,就没有理由去读取和哈希 "语言"。 我认为规划师根本不承认这个舞蹈。