RedShift / ParAccel中UNION选择查询的性能非常糟糕

时间:2013-11-19 19:58:07

标签: amazon-redshift paraccel

我在redshift中有两个表:

  • tbl_current_day - 约4.5M行
  • tbl_previous_day - 大约4.5M行,与tbl_current_day完全相同的数据

除此之外,我还有一个名为 qry_both_days 的视图定义如下:

CREATE OR REPLACE qry_both_days AS 
SELECT * FROM tbl_current_day
UNION SELECT * FROM tbl_previous_day;

当我在其中一个单独的表上运行查询时,我获得了预期的非常好的性能。 例如,以下查询运行5秒:

select count(distinct person_id) from tbl_current_day;
-- (person_id is of type int)

解释计划:

 XN Aggregate  (cost=1224379.82..1224379.82 rows=1 width=4)
   ->  XN Subquery Scan volt_dt_0  (cost=1224373.80..1224378.61 rows=481 width=4)
         ->  XN HashAggregate  (cost=1224373.80..1224373.80 rows=481 width=4)
               ->  XN Seq Scan on tbl_current_day  (cost=0.00..979499.04 rows=97949904 width=4)

请注意,宽度是4个字节,因为它应该是,因为我的列是int类型。

HOWEVER ,当我在 qry_both_days 上运行相同的查询时,查询运行速度慢了20倍,而我预计它的运行速度只会慢2倍,因为它应该会运行超过两次行:

select count(distinct person_id) from qry_both_days;

解释计划:

 XN Aggregate  (cost=55648338.34..55648338.34 rows=1 width=4)
   ->  XN Subquery Scan volt_dt_0  (cost=55648335.84..55648337.84 rows=200 width=4)
         ->  XN HashAggregate  (cost=55648335.84..55648335.84 rows=200 width=4)
               ->  XN Subquery Scan qry_both_days  (cost=0.00..54354188.49 rows=517658938 width=4)
                     ->  XN Unique  (cost=0.00..49177599.11 rows=517658938 width=190)
                           ->  XN Append  (cost=0.00..10353178.76 rows=517658938 width=190)
                                 ->  XN Subquery Scan "*SELECT* 1"  (cost=0.00..89649.20 rows=4482460 width=190)
                                       ->  XN Seq Scan on tbl_current_day  (cost=0.00..44824.60 rows=4482460 width=190)
                                 ->  XN Subquery Scan "*SELECT* 2"  (cost=0.00..90675.00 rows=4533750 width=187)
                                       ->  XN Seq Scan on tbl_previous_day  (cost=0.00..45337.50 rows=4533750 width=187)

问题:宽度现在是190,而不是4个字节,因为它应该是!!! 有谁知道如何使RedShift只选择UNION SELECT上的相关列?

谢谢!

2 个答案:

答案 0 :(得分:4)

本身使用的

UNION会删除重复的行,例如,根据SQL规范使用隐含的DISTINCT

这意味着准备输出需要更多的处理。

如果您不想要DISTINCT结果,那么您应该始终使用UNION ALL来确保数据库没有检查潜在的欺骗行为。

答案 1 :(得分:1)

您的视图创建为SELECT *,因此它始终查询所有列以为视图创建数据。 然后使用另一个SELECT,只返回视图中请求的列。

如果您选择的列数有限(例如一直使用的两个,三个集合),我会为每个列集创建一个单独的视图。

另一种方式(甚至比以前更不优雅)是调用每个视图,使其名称显示包含哪些列(假设用“__”排序和分隔) - 如qry_both_days__age__name__person_id。然后,在每个查询之前,检查是否存在所需的视图,如果不创建它。