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

die*_*cht 1 paraccel amazon-redshift

我在红移中有两个表:

  • tbl_current_day - 大约 450 万行
  • tbl_previous_day - 大约 450 万行,数据与 tbl_current_day 完全相同

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

CREATE OR REPLACE qry_both_days AS 
SELECT * FROM tbl_current_day
UNION SELECT * FROM tbl_previous_day;
Run Code Online (Sandbox Code Playgroud)

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

select count(distinct person_id) from tbl_current_day;
-- (person_id is of type int)
Run Code Online (Sandbox Code Playgroud)

解释计划:

 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)
Run Code Online (Sandbox Code Playgroud)

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

但是,当我在qry_both_days上运行相同的查询时,该查询的运行速度要慢 20 倍,而我预计它的运行速度只会慢 2 倍,因为它应该多运行两倍的行:

select count(distinct person_id) from qry_both_days;
Run Code Online (Sandbox Code Playgroud)

解释计划:

 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)
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Joe*_*ris 5

UNIONDISTINCT根据 SQL 规范,单独使用会删除重复的行,例如,使用隐含的。

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

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

  • 从经验上看,这实际上似乎是真正的问题,至少在 2015 年第三季度。我正在创建两个完整的相同宽度表的并集的视图,一个包含 ~1B 行,一个包含 ~8B 行......使用`SELECT * [..] UNION SELECT [..]`和`SELECT * [..] UNION ALL SELECT * [..]`的视图之间的区别非常明显。`UNION ALL` 比单表 `SELECT` 贵大约 5%,而`UNION` 大约是它的 150 倍。这是带有注释的“EXPLAIN”输出的要点 - https://gist.github.com/slpsys/5e43d8237fd8aa924015 (3认同)