本文共 768 字,大约阅读时间需要 2 分钟。
子查询和子连接不同,它不是“表达式”,它是“表”。因此,优化器把子查询当做表来对待,从而针对子查询产生的是一个扫描路径,也就是 SubQueryScan。
如果把子查询看做一个表,我们可以叫它“子查询表”,这个子查询表和其他表在做连接(Join)操作。子查询如果被提升,会转换成子查询中的表直接与与上层的表做连接操作。查询优化模块对表之间的连接操作的优化做了很多工作,因此可能获得更好的执行计划。PostgreSQL 提升了 3 种类型的子查询:SIMPLE 子查询、VALUES 子查询和 UNION 子查询,我们分别来看一下这 3 种子查询的提升。
所谓 SIMPLE 子查询,实际上就是经典的子查询。对于 SIMPLE 子查询,我们先看一下它的提升条件。首先要求子查询的类型是真的“简单”(simple)的。所谓的简单,需要满足如下条件:不能包含聚集操作、窗口函数、GROUP 操作等。在子连接提升的时候我们已经见过类似的条件,下面的例子中子查询中包含了聚集函数 avg,不能提升。
postgres=# EXPLAIN SELECT * FROM TEST_A, (SELECT avg(a) FROM TEST_B) b; QUERY PLAN-------------------------------------------------------------------- Nested Loop (cost=2.25..5.27 rows=100 width=48) -> Aggregate (cost=2.25..2.26 rows=1 width=32) -> Seq Scan on test_b
转载地址:http://yoyni.baihongyu.com/