postgresql 下面两个查询的输出是否相同,为什么第一个查询的性能比第二个查询的性能好得多?

bxgwgixi  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(1)|浏览(172)

查询1:

select *  
from a
              LEFT JOIN p ON a.product_id = p.web_id
              LEFT JOIN m ON p.manufacturer_id = m.web_id
              LEFT JOIN a add ON a.address_id = add.web_id
              LEFT JOIN c ON c.web_id = a.owner_id
              LEFT JOIN a ca ON c.main_address_id = ca.web_id
              LEFT JOIN d ON a.web_id = d.equipment_id
              LEFT JOIN s ON d.last_segment_id = s.web_id
              LEFT JOIN oh ON s.order_header_id = oh.web_id
              LEFT JOIN f ON s.folder_id = f.web_id
              LEFT JOIN ve on a.web_id = ve.equipment_id
where ve.date_updated >= now() - interval '10000 min'

查询二:

select *  
from a
              LEFT JOIN p ON a.product_id = p.web_id
              LEFT JOIN m ON p.manufacturer_id = m.web_id
              LEFT JOIN ve on a.web_id = ve.equipment_id
              LEFT JOIN a add ON a.address_id = add.web_id
              LEFT JOIN c ON c.web_id = a.owner_id
              LEFT JOIN a ca ON c.main_address_id = ca.web_id
              LEFT JOIN d ON a.web_id = d.equipment_id
              LEFT JOIN s ON d.last_segment_id = s.web_id
              LEFT JOIN oh ON s.order_header_id = oh.web_id
              LEFT JOIN f ON s.folder_id = f.web_id
where ve.date_updated >= now() - interval '10000 min'

这两个查询之间的唯一区别是左join with ve表的位置。
我相信这两个查询的输出总是相同的,对吗?
查询1能够在5秒内执行,而查询2持续约4分钟。表a中的记录总数约为2000万条。为什么查询1更快?

8mmmxcuj

8mmmxcuj1#

连接条件的顺序并不重要,查询在语义上是相同的。执行时间差必须连接到join_collapse_limit
每当生成不超过这个数量的项目列表时,计划器将将显式JOIN结构(FULL JOIN s除外)重写为FROM项目列表。较小的值会减少计划时间,但可能会产生较差的查询计划。
默认情况下,此变量的设置与from_collapse_limit相同,这适用于大多数用途。将其设置为1可防止对显式JOIN s进行任何重新排序。因此,查询中指定的显式联接顺序将是联接关系的实际顺序。由于查询计划器并不总是选择最佳连接顺序,高级用户可以选择暂时将此变量设置为1,然后显式指定他们所需的连接顺序。更多信息请参见Section 14.3
请注意,查询连接八个以上的表。
如果您有很多这样的连接,并且不想重写它们,并且您不介意优化器花费更多的时间,那么可以增加join_collapse_limitfrom_collapse_limit

相关问题