与子查询相比,使用With,SQL查询需要更长的时间

时间:2017-05-17 07:38:36

标签: sql postgresql common-table-expression dbeaver

我有点困惑为什么使用with子句的简单SQL查询比将它们放在子查询中花费的时间长得多。我的IDE上用于&gt; 10mil记录的实例使用with子句运行&gt; 30分钟,使用子查询仅运行<10秒。

下面列出一个简单的例子:

with table1 as (select tb1.a, tb1.b, tb2.c, tb3.d
                from tablea
                where a > 0 and b = 2016)
     table2 as (select a, b, c, d, e, f
                from table1 tb1
                left join table2 tb2 on tb1.a=tb2.a
                left join table3 tb3 on tb1.b=tb2.b)
select * from table2

相比将它们作为子查询添加:

select * from (select a, b, c, d, e, f
                from (select tb1.a, tb1.b, tb2.c, tb3.d
                      from tablea
                      where a > 0 and b = 2016) tb1
                left join table2 tb2 on tb1.a=tb2.a
                left join table3 tb3 on tb1.b=tb2.b) table2

后一个查询的完成速度比前者快得多。但是,前者在查询结构上看起来要容易得多,所以如果可能的话我会更喜欢。

我想知道我在解释时使用的IDE(DBeaver)存在巨大的差异,或者它基于SQL语句逻辑本身?

谢谢。

1 个答案:

答案 0 :(得分:2)

这是因为在Postgres中,CTE充当了优化障碍。解决方法(具有几乎相同的句法结构)是用TEMP VIEW替换CTE:

CREATE TEMP VIEW v1 AS
        SELECT ta.a, ta.b, ta.c, ta.d
        FROM tablea ta
        WHERE a > 0 and b = 2016
        ;
CREATE TEMP VIEW v2 AS
        SELECT a, b, c, d, e, f
        FROM v1
        LEFT JOIN table2 tb2 ON v1.a=tb2.a
        LEFT JOIN table3 tb3 ON v1.b=tb3.b
        ;
SELECT * from v2;