Redshift - 重新设计表以使用 DIST 和 SORT 键(性能问题)

Posted

技术标签:

【中文标题】Redshift - 重新设计表以使用 DIST 和 SORT 键(性能问题)【英文标题】:Redshift - Redesign tables to use DIST and SORT keys (performance issue) 【发布时间】:2019-05-11 12:01:07 【问题描述】:

我在 Redshift 上遇到了严重的性能问题,我已经开始重新考虑我的表结构。

现在,我正在识别仪表板上最重要的表格。首先,我运行以下查询:

SELECT * FROM admin.v_extended_table_info
WHERE table_id IN (
  SELECT DISTINCT s.tbl FROM stl_scan s
    JOIN pg_user u ON u.usesysid = s.userid
    WHERE s.type=2 AND u.usename='looker'
  )
ORDER BY SPLIT_PART("scans:rr:filt:sel:del",':',1)::int DESC,
  size DESC;

根据查询结果,我可以识别出许多分布为EVEN 的小表(1-1000 条记录),也可能是ALL - 这些表用于很多连接指令。

除此之外,我发现我的 99% 的表都在使用 EVEN 而没有排序键。我没有使用非规范化表,因此我需要运行大量连接来获取数据——据我所知,EVEN 不适合连接,因为它可以分布在网络上。

我有 3 个与工单流相关的表:用户、工单和工单历史记录。所有这些表都是EVEN,没有排序键,diststyle 为EVEN

现在,我想重新设计表 user:此表用于连接条件 ticket.user_id = user.id 和 where 子句,如 user.email = 'xxxx@xxxx.com'user.email like '%@something.com%'group by user.email

我打算做的第一件事是使用 diststyle 作为分布,并使用 id 的键。使用唯一值作为 dist 键有意义吗?我已经阅读了很多关于 dist 键的帖子,但仍然让我感到困惑。

由于排序键有意义,所以使用电子邮件作为复合键?我已经阅读以避免像日期、时间戳或身份一样增长的列,这就是为什么我不使用它作为交错。为了避免like,我计划创建一个新列来识别什么是电子邮件域。

之后,我会将小表更改为 dist ALL 并再次尝试查询。

我走对了吗?还有什么提示吗?

这个问题听起来很愚蠢,但我的技术背景只是软件开发,我正在学习 Redshift 并阅读大量文档。

【问题讨论】:

【参考方案1】:

基本的经验法则是:

DISTKEY 设置为JOINs 中最常用的列 将SORTKEY 设置为WHEREs 中最常用的列

你说得对,小表可以有ALL的分布,这样可以避免在节点之间发送数据。

DISTKEY 在通过两个表中具有相同DISTKEY 的公共列连接表时提供最大的好处。这意味着每一行都包含在同一个节点上,并且不需要在节点(或更准确地说,切片)之间发送数据。但是,您只能选择一个DISTKEY,因此请在最常用于JOIN 的列上选择。

当 Redshift 可以跳过存储块时,

SORTKEY 提供了最大的好处。每个存储块包含一列的数据,并标有MINMAX 值。当表按特定列排序时,它会最小化包含给定列值数据的磁盘块的数量(因为它们都位于一起,而不是随机分布在整个磁盘存储中)。因此,请使用WHERE 语句中最常用的列。

如果user.email 通配符搜索速度很慢,您当然可以使用域创建一个新列。或者,为了获得更好的性能,您可以考虑创建一个单独的查找表,其中仅包含 user_iddomain,具有 SORTKEY = domain。这将在按域搜索时执行得最快。

经验提示:我建议不要将电子邮件地址用作user_id,因为人们有时想更改电子邮件地址。最好为此类id 列使用唯一编号,并将电子邮件地址作为可变属性。 (我已经看到软件系统需要进行重大改写来修复这样一个早期的设计决策!)

【讨论】:

关于在 JOIN 上使用的表上使用 dist 样式作为 KEY 而不是 EVEN?有意义吗? ALL 对于小桌子来说很棒。 DISTKEY 和指定的 KEY 很棒,如上所述。剩下的EVEN 用于不是连接最多的表。这是一种“不在乎”的选择。另见:Amazon Redshift Best Practices for Designing Tables - Amazon Redshift

以上是关于Redshift - 重新设计表以使用 DIST 和 SORT 键(性能问题)的主要内容,如果未能解决你的问题,请参考以下文章

如果我使用 COPY 命令将数据从 S3 加载到 Redshift,它会遵循我的 dist 样式和键吗?

为啥 Redshift 需要进行全表扫描才能找到 DIST/SORT 键的最大值?

Redshift:主表的 DIST KEY 和 SORT KEY 的适当组合是啥?

在 Redshift 中,如何复制表、添加 dist 和排序键以及保留列编码?

Redshift 时间序列数据库的 Dist/Sort 键

当两个表具有相同的 dist 和 sort 键,但列名不同时,Redshift 是不是执行合并连接?