【问题标题】:Query optimization in greenplumgreenplum 中的查询优化
【发布时间】:2017-08-30 06:08:39
【问题描述】:

我有一个问题

SELECT ROW_NUMBER() OVER (ORDER BY getdate()) AS ID, GETDATE() as time, tmp.* from 
( select RecordType, TrnYear, SUM(MonthlySales) as AnnualSales
FROM vwKPI_SalesGraphMonthly
WHERE RecordType = 'A'
GROUP BY RecordType, TrnYear

UNION ALL

SELECT RecordType, TrnYear, SUM(MonthlySales) as AnnualSales
FROM vwKPI_SalesGraphMonthly
WHERE RecordType = 'B'
GROUP BY RecordType, TrnYear

UNION ALL

SELECT RecordType, TrnYear, SUM(MonthlySales) as AnnualSales
FROM vwKPI_SalesGraphMonthly
WHERE RecordType = 'R'
GROUP BY RecordType, TrnYear

UNION ALL

SELECT 'Y', TrnYear, SUM(MonthlySales) as AnnualSales
FROM vwKPI_SalesGraphMonthly CROSS JOIN ArControl  
25 THEN FinPeriod -1 ELSE FinPeriod END)
WHERE RecordType = 'B' AND TrnMonth <=DATE_PART('month', GETDATE())
GROUP BY RecordType, TrnYear
) tmp

vwKPI_SalesGraphMonthly 是另一个大约 300 行的查询。 我不想在此查询中插入 vwKPI_SalesGraphMonthly 的定义 4 次。有没有办法在查询中只声明一次vwKPI_SalesGraphMonthly 的定义并在所有联合中使用它。

【问题讨论】:

  • Greenplum 是否支持common table expressions
  • 是的,Greenplum 支持 CTE,根据我的经验,如果您使用 CTE,性能会下降

标签: sql greenplum


【解决方案1】:

是的,CTE 可通过set optimizer=on 获得。

Pivotal 查询优化器处理包含 WITH 子句的查询。 WITH 子句也称为公用表表达式 (CTE),生成仅为查询而存在的临时表。此示例查询包含 CTE。

WITH v AS (SELECT a, sum(b) as s FROM T where c < 10 GROUP BY a)
  SELECT *FROM  v AS v1 ,  v AS v2
  WHERE v1.a <> v2.a AND v1.s < v2.s;

作为查询优化的一部分,Pivotal 查询优化器可以将谓词下推到 CTE 中。例如查询,Pivotal Query Optimizer 将相等谓词推送到 CTE。

WITH v AS (SELECT a, sum(b) as s FROM T GROUP BY a)
  SELECT *
  FROM v as v1, v as v2, v as v3
  WHERE v1.a < v2.a
    AND v1.s < v3.s
    AND v1.a = 10
    AND v2.a = 20
    AND v3.a = 30;

Pivotal 查询优化器可以处理以下类型的 CTE: 定义一个或多个表的 CTE。在此查询中,CTE 定义了两个表。

WITH cte1 AS (SELECT a, sum(b) as s FROM T 
               where c < 10 GROUP BY a),
      cte2 AS (SELECT a, s FROM cte1 where s > 1000)
  SELECT *
  FROM cte1 as v1, cte2 as v2, cte2 as v3
  WHERE v1.a < v2.a AND v1.s < v3.s;
Nested CTEs.
WITH v AS (WITH w AS (SELECT a, b FROM foo 
                      WHERE b < 5) 
           SELECT w1.a, w2.b 
           FROM w AS w1, w AS w2 
           WHERE w1.a = w2.a AND w1.a > 2)
  SELECT v1.a, v2.a, v2.b
  FROM v as v1, v as v2
  WHERE v1.a < v2.a; 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    • 2011-09-14
    • 1970-01-01
    相关资源
    最近更新 更多