我有一个非常技术性的问题,关于Redshift如何在内部处理DISTKEY
和SORTKEY
以便满足存储层和查询执行需求。我已经读过这本令人惊叹的post,该书很好地解释了每种与餐桌设计有关的含义。
我的问题是,假设我有一个表 A ,其中有三列:
CREATE TABLE (
orderdate timestamp distkey,
product_id varchar(50),
product_name varchar(250)
) SORTKEY (product_id)
现在,我们知道Redshift是针对数据仓库进行优化的列式方法数据库。在我的示例中很明显,可能是如何在计算节点的切片之间分配数据的方式基于DISTKEY
排序日期。但是,列product_id
和product_name
会发生什么?这些与orderdate
一起分布在同一切片上,然后在我执行查询时Redshift使用基于我的SORTKEY
的区域图来指出具有数据的列的区域并进行检索吗?
如果Redshift是一种列式方法,那么每一列是否都应该有不同的存储方式?或这的真正含义是:基于一个明智地选择的列,整个列将与DISTKEY
一起存储在同一片上,然后保证用户甚至可以集中精力查询特定区域以提取所需数据。所以我总体来说可能是这样的:
DISTKEY
存储层和SORTKEY
查询执行行为
现在,如果我使用DISTKEY
,那么我的数据将按守时的列顺序进行存储,因此,如果以后再使用SORTKEY
,我的DISTKEY
将不能更改或更改,以便它如何工作?
如果我做错了,那么对不起大家,但是我需要很好地理解这种架构如何在内部驱动数据。非常感谢
更新
基于@JoeHarris帖子回答了这个问题,我试图描绘出数据可能看起来如何存储。
第一个分发级别是我的DISTKEY
(日期不好,但仅以相同的示例为例),然后根据我的SORTKEY
在内部进行红移排序,给出如下内容:
感谢您的反馈
答案 0 :(得分:4)
DISTKEY
在切片之间分布行。
在您的示例中,具有给定orderdate
的所有行将位于同一切片中。这意味着这些行的所有列都在该切片中。
如果两个表具有相同的DISTKEY,则两个表中具有DISTKEY列值的所有行都将位于同一片上。
顺便说一句,日期和时间戳不是DISTKEY的理想选择,因为它们很少在JOIN
中使用。像product_id
这样的唯一标识符将使DISTKEY更好。一般规则是使用出现在最多/最大的JOIN中的列。
SORTKEY
确定表中行的排序方式。对于每个切片上存储的行,它们以SORTKEY顺序存储。每列的数据存储在单独的块中(很可能每列使用许多块),但是在列块中,行的顺序相同。
例如,如果一个表有三列,则每个切片将至少占据三个块(每列一个)。在这些列块中,行的顺序相同。
每个块还具有最小值和最大值(“区域映射”),这使Redshift非常容易“跳过”不包含所需值的块。由于磁盘访问是操作中最慢的部分,因此可以大大提高性能。