我在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;
根据查询结果,我可以识别出许多小的表(1-1000条记录),这些表以EVEN
的形式分布,并且可能是ALL
-该表在许多联接中使用说明。
此外,我已经确定99%的表使用的是EVEN
,而没有排序键。我没有使用非规范化表,因此我需要运行大量的联接来获取数据-就我所读的内容而言,EVEN
不利于联接,因为它可以分布在网络上。
我有3个与工单流相关的表:user,ticket和ticket_history。所有这些表都是EVEN
,没有排序键,而diststyle为EVEN
。
现在,我想重新设计表user
:此表按条件ticket.user_id = user.id
和其中诸如user.email = 'xxxx@xxxx.com'
或user.email like '%@something.com%'
或{{1 }}。
我打算做的第一件事是使用diststyle作为发行版,将密钥用作group by user.email
。使用唯一值作为dist键有意义吗?我已经阅读了很多有关dist键的文章,但仍然让我感到困惑。
由于排序键有意义,因此可以将电子邮件用作复合词?我已经读过以避免像日期,时间戳或标识那样增长的列,这就是为什么我不以交错方式使用它的原因。为了避免出现id
,我计划创建一个新列来标识什么是电子邮件域。
之后,我将小表更改为dist like
,然后重试查询。
我走对了吗?还有其他提示吗?
这个问题听起来很愚蠢,但我的技术背景只是软件开发,我正在学习Redshift并阅读了大量文档。
答案 0 :(得分:2)
基本的经验法则是:
DISTKEY
设置为JOINs
中最常用的列SORTKEY
设置为WHEREs
中最常用的列您是正确的,小表可以具有ALL
的分布,这样可以避免在节点之间发送数据。
DISTKEY
的公共列联接表时, DISTKEY
提供最大的好处。这意味着每一行都包含在同一节点上,并且不需要在节点之间(或更准确地说是切片)之间发送数据。但是,您只能选择一个DISTKEY
,因此请在JOIN
最常使用的列上进行选择。
SORTKEY
提供了最大的好处。每个存储块都包含一列的数据,并用MIN
和MAX
值标记。当在特定列上对表进行排序时,它会减少包含给定列值的数据的磁盘块的数量(因为它们都位于一起,而不是随机分布在整个磁盘存储中)。因此,请使用WHERE
语句中最常用的列。
如果user.email
通配符搜索缓慢,则可以确定使用域创建新列。或者,为了获得更好的性能,您可以考虑使用user_id
和domain
和SORTKEY = domain
创建单独的查找表。按域搜索时,执行速度最快。
经验提示:我建议不要将电子邮件地址用作user_id
,因为人们有时希望更改电子邮件地址。最好对此类id
列使用唯一的数字,并将电子邮件地址作为可更改的属性。 (我已经看到软件系统需要进行大量重写才能修复这样的早期设计决策!)