将sortkey的顺序更改为降序

时间:2016-08-23 18:17:20

标签: amazon-web-services amazon-redshift

我们有一个2节点的Redshift集群,其中一个表有大约100M的记录。我们将timestamp列标记为sortkey - 因为查询总是受时间限制。但是,我们的用例要求结果必须按降序排序(在sortkey上)。

经过一些基准测试后,我们注意到平均时间约为10秒。但是,当删除反向排序时,平均时间降至1秒以下。

是否可以将sortkey的顺序颠倒为降序?官方文件似乎并未表明这是可能的。但是我在创建新表时尝试了这个:

sortkey(start_time DESC)

没有错误,但似乎没有任何影响。

编辑:在查询中添加了EXPLAIN语句的结果。

  • 使用order_by ASC的查询

      explain select * from kcdr_sr_desc where user_id=396747 and start_time > '2016-01-01' and start_time < '2016-07-01' order by start_time limit 20;
    

    结果:

        XN Limit  (cost=0.00..10.86 rows=20 width=300)
        ->  XN Merge  (cost=0.00..709235.56 rows=1306585 width=300)
           Merge Key: start_time
            ->  XN Network  (cost=0.00..709235.56 rows=1306585 width=300)
           Send to leader
           ->  XN Seq Scan on kcdr_sr_desc  (cost=0.00..709235.56 rows=1306585 width=300)
                 Filter: ((user_id = 396747) AND (start_time > '2016-01-01 00:00:00'::timestamp without time zone) AND (start_time < '2016-07-01 00:00:00'::timestamp without time zone))
    
  • 使用order_by DESC的查询

     explain select * from kcdr_sr_desc where user_id=396747 and start_time > '2016-01-01' and start_time < '2016-07-01' order by start_time desc limit 20
    

    结果:

      XN Limit  (cost=1000000841967.42..1000000841967.47 rows=20 width=300)
      ->  XN Merge  (cost=1000000841967.42..1000000845233.88 rows=1306585 width=300)
      Merge Key: start_time
         ->  XN Network  (cost=1000000841967.42..1000000845233.88 rows=1306585 width=300)
           Send to leader
           ->  XN Sort  (cost=1000000841967.42..1000000845233.88 rows=1306585 width=300)
                 Sort Key: start_time
                 ->  XN Seq Scan on kcdr_sr_desc  (cost=0.00..709235.56 rows=1306585 width=300)
                       Filter: ((user_id = 396747) AND (start_time > '2016-01-01 00:00:00'::timestamp without time zone) AND (start_time < '2016-07-01 00:00:00'::timestamp without time zone))
    

1 个答案:

答案 0 :(得分:1)

Amazon Redshift表上的SORTKEY用于通过使用区域地图来提高查询效率。它不打算对数据进行排序以匹配查询。

Amazon Redshift将数据存储在1MB块的磁盘上。每个块包含与一个表的一列相关的数据,并且来自该列的数据可以占用多个块。块可以被压缩,因此它们通常包含超过1MB的数据。

磁盘上的每个块都有一个关联的区域映射,用于标识该块中存储的列的最小值和最大值。这使Redshift能够跳过不包含相关数据的块。例如,如果SORTKEY是时间戳并且查询具有将数据限制为特定日期的WHERE子句,则Redshift可以跳过所需日期不在该块内的任何块。< / p>

一旦Redshift找到具有所需数据的块,它将读取这些块以执行查询。

在查看您的EXPLAIN计划时,第二个示例显然有一个额外的SORT步骤。看起来查询优化器知道您正在对与SORTKEY匹配的列进行排序,因此在第一个示例中跳过了排序。这通常是附加到表的数据,导致更新的数据出现在列的末尾。

为您提供的一些选项:

  • 如果您总是在进行新的数据加载,则可以添加与日期相反的新列(例如,从3000年减去存储日期的时间间隔) 。将其用作SORTKEY,数据将反向存储。实际日期列的区域地图也可以方便地进行反向排序。

  • 如果您不断加载新数据,最新数据将附加到列的末尾,因此无论如何都无法轻松地对数据进行反向排序。

  • 使用较小的日期范围。上述查询将结果限制在六个月的范围内,返回1,306,585行。然后查询将结果限制为最近20的结果。如果减少日期范围(例如减少到一天),将检索的数据越少,排序运行得越快,查询将越快。鉴于行数很多,每天平均有7000多条记录,因此对LIMIT 20来说应该足够了。

  • 不要使用SELECT * - 它会导致从磁盘读取更多块(因为每列都存储在一个单独的块中)。通过仅查询实际需要的列,可以减少磁盘访问,并且查询运行得更快。