AnalyticDB PostgreSQL版7.0版本增強了公用表表達式(Common Table Expression,簡稱CTE)功能,支持對CTE語句指定MATERIALIZED或NOT MATERIALIZED,可以更好地控制執(zhí)行計劃,能夠有效提升SQL性能。

功能簡介

CTE可以在單個語句的執(zhí)行范圍內(nèi)定義臨時結(jié)果集,該結(jié)果集只在查詢期間有效。CTE可以自引用,也可在同一查詢中多次引用,實現(xiàn)了代碼段的重復(fù)利用。常見CTE語句格式如下:

WITH x1 AS
(SELECT a FROM t1),
x2 AS
(SELECT b FROM t1)
SELECT * FROM
x1 JOIN x2 ON x1.a = x2.b;

CTE對查詢語句有如下兩種處理方法:

  • MATERIALIZED:先在WITH子查詢內(nèi)部進行計算,然后再匯總計算。
  • NOT MATERIALIZED:將WITH子查詢強行拉取到父查詢中進行計算。

7.0版本以前,數(shù)據(jù)庫的優(yōu)化器會自行決定采用上述的其中一種方法。7.0版本以后,您可以通過指定MATERIALIZED或NOT MATERIALIZED來干預(yù)上述行為。示例如下:

  • 指定MATERIALIZED
    EXPLAIN WITH x1 AS MATERIALIZED (SELECT * FROM t1) SELECT * FROM x1 WHERE a > 1;

    通過執(zhí)行計劃可以看出,系統(tǒng)先計算了子查詢,再進行匯總計算。

                                        QUERY PLAN
    ---------------------------------------------------------------------------------------
     Gather Motion 3:1 (slice1; segments:3) (cost=0.00..3085.25 rows=86100 width=8)
         -> Subquery Scan on x1 (cost=0.00..1937.25 rows=28700 width=8)
             Filter: (x1.a > 1)
             -> Shared Scan (share slice:id 1:0) (cost=321.00..355.50 rows=28700 width=8)
                 -> Seq Scan on t1 (cost=0.00..321.00 rows=28700 width=8)
     Optimizer: Postgers query optimizer
    (6 rows)
  • 指定NOT MATERIALIZED
    EXPLAIN WITH x1 AS NOT MATERIALIZED (SELECT * FROM t1) SELECT * FROM x1 WHERE a > 1;

    通過執(zhí)行計劃示例可以看出,系統(tǒng)直接將子查詢拉取到父查詢中進行計算。

                                        QUERY PLAN
    ------------------------------------------------------------------------------
     Gather Motion 3:1 (slice1; segments:3) (cost=0.00..775.42 rows=28700 width=8)
         -> Seq Scan on t1 (cost=0.00..392.75 rows=9567 width=8)
             Filter: (a > 1)
     Optimizer: Postgres query optimizer
    (4 rows)

示例

  • 示例一:不使用CTE時的執(zhí)行計劃

    查看一個三表JOIN的執(zhí)行計劃,通過以下執(zhí)行計劃可以看出,默認(rèn)JOIN順序為表t1先JOIN表t2后再JOIN表t3。

    CTE計劃增強-3
  • 示例二:使用CTE時指定MATERIALIZED

    通過指定MATERIALIZED的方式改變JOIN順序,通過以下執(zhí)行計劃可以看出,JOIN順序變?yōu)楸韙1先JOIN表t3后再JOIN表t2。

    CTE計劃增強-4
  • 示例三:使用CTE時指定MATERIALIZED

    通過指定MATERIALIZED的方式改變JOIN順序,通過以下執(zhí)行計劃可以看出,JOIN順序變?yōu)楸韙2先JOIN表t3后再JOIN表t1。

    CTE計劃增強-5