Amazon web services 将sortkey的顺序更改为降序

Amazon web services 将sortkey的顺序更改为降序,amazon-web-services,amazon-redshift,Amazon Web Services,Amazon Redshift,我们有一个2节点的红移集群,其中一个表包含大约100万条记录。我们将时间戳列标记为sortkey,因为查询总是有时间限制的。然而,我们的用例要求结果必须按降序排序(在sortkey上) 经过一些基准测试后,我们注意到平均时间约为10秒。然而,当取消反向排序时,平均时间降到1s以下 是否可以将sortkey的顺序颠倒为降序?官方文件似乎没有表明这是可能的。但是,在创建新表时,我尝试放置以下内容: sortkey(start_time DESC) 没有错误,但似乎没有任何效果 编辑:在查询中添加E

我们有一个2节点的红移集群,其中一个表包含大约100万条记录。我们将时间戳列标记为sortkey,因为查询总是有时间限制的。然而,我们的用例要求结果必须按降序排序(在sortkey上)

经过一些基准测试后,我们注意到平均时间约为10秒。然而,当取消反向排序时,平均时间降到1s以下

是否可以将sortkey的顺序颠倒为降序?官方文件似乎没有表明这是可能的。但是,在创建新表时,我尝试放置以下内容:

sortkey(start_time DESC)
没有错误,但似乎没有任何效果

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

  • 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;
    
    explain select*from kcdr_sr_desc,其中用户id=396747,开始时间>'2016-01-01'和开始时间<'2016-07-01'订单,按开始时间限制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))
    
      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))
    
    XN限制(成本=0.00..10.86行=20宽=300)
    ->XN合并(成本=0.00..709235.56行=1306585宽度=300)
    合并键:开始时间
    ->XN网络(成本=0.00..709235.56行=1306585宽度=300)
    送交领导
    ->kcdr_sr_desc上的XN序列扫描(成本=0.00..709235.56行=1306585宽度=300)
    过滤器:((用户id=396747)和(开始时间>'2016-01-01 00:00:00':无时区的时间戳)和(开始时间<'2016-07-01 00:00:00':无时区的时间戳))
    
  • 按DESC排序的带有order_的查询

     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
    
    explain select*from kcdr_sr_desc,其中用户id=396747和开始时间>'2016-01-01'和开始时间<'2016-07-01'按开始时间描述限制订购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))
    
      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))
    
    XN限制(成本=1000000841967.42..1000000841967.47行=20宽=300)
    ->XN合并(成本=1000000841967.42..1000000845233.88行=1306585宽度=300)
    合并键:开始时间
    ->XN网络(成本=1000000841967.42..1000000845233.88行=1306585宽度=300)
    送交领导
    ->XN排序(成本=1000000841967.42..1000000845233.88行=1306585宽度=300)
    排序键:开始时间
    ->kcdr_sr_desc上的XN序列扫描(成本=0.00..709235.56行=1306585宽度=300)
    过滤器:((用户id=396747)和(开始时间>'2016-01-01 00:00:00':无时区的时间戳)和(开始时间<'2016-07-01 00:00:00':无时区的时间戳))
    

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

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

磁盘上的每个块都有一个相关的区域映射,该映射标识了该块中存储的列的最小值和最大值。这允许红移跳过不包含相关数据的块。例如,如果
SORTKEY
是一个时间戳,并且查询具有一个
WHERE
子句,该子句将数据限制在特定的日期,那么红移可以跳过所需日期不在该块内的任何块

一旦Redshift找到了包含所需数据的块,它将读取这些块以执行查询

在查看您的
EXPLAIN
计划时,第二个示例显然有一个额外的
SORT
步骤。查询优化器似乎知道您正在对与
SORTKEY
匹配的列进行排序,因此在第一个示例中跳过排序。这在将数据追加到表中的情况下很常见,这会导致较新的数据出现在列的末尾

您的一些选择:

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

  • 如果不断加载新数据,最新数据将附加到列的末尾,因此无论如何都不能轻松地保持数据的反向排序

  • 使用较小的日期范围。上面的查询将结果限制在六个月的范围内,返回1306585行。然后查询对其进行排序,并将结果限制为最近的20个。如果减少日期范围(例如,仅为一天),则检索的数据将越少,排序将运行得更快,查询也将更快。考虑到这么多行,平均每天有7000多条记录,因此对于
    限制20
    ,这应该足够了

  • 不要使用
    选择*
    ——这会导致从磁盘读取更多块(因为每列存储在单独的块中)。通过只查询实际需要的列,磁盘访问将减少,查询运行速度也将加快


红移中没有升序或降序排序键的概念。你的基准测试结果令我惊讶。您确定这不是由代码编译引起的吗?()@GuiSim我在这两种查询中添加了EXPLAIN的结果-显然,带有order_by as DESC的查询似乎成本更高。如果我没有错的话——它在返回结果之前对整个数据范围进行排序。我只是想说第一个选项对我的用例非常有效。此外,选择所需的列而不是使用select*也将性能提高了很多。非常感谢你!