如何优化与自身连接表的红移查询?

Posted

技术标签:

【中文标题】如何优化与自身连接表的红移查询?【英文标题】:How to optimize a redshift query that join table with itself? 【发布时间】:2020-10-15 04:19:09 【问题描述】:

假设我有一个事务表

CREATE TABLE IF NOT EXISTS txn_raw (
transaction_id VARCHAR(60),
sport_label VARCHAR(300),
family_label VARCHAR(150),
item_label VARCHAR(150)
)
DISTKEY (the_transaction_id)
SORTKEY (the_transaction_id, sport_label, family_label, item_label)
;
COMMIT;

我想优化以下查询以计算项目之间的相关性。

SELECT 
a.sport_label as sport_label_a, 
a.family_label as family_label_a, 
a.dsm_label as dsm_label_a, 
b.sport_label as sport_label_b, 
b.family_label as family_label_b, 
b.dsm_label as dsm_label_b, 
count(distinct a.the_transaction_id) as txn_ab
FROM txn_raw a
JOIN txn_raw b 
on a.the_transaction_id=b.the_transaction_id
and a.sport_label != b.sport_label
and a.family_label != b.family_label
and a.item_label != b.item_label
group by 1,2,3,4,5,6

我正在考虑在加入 txn_raw 后创建一个临时表来存储数据。 然后查询临时表并进行分组。

有没有更好的方法来优化这种查询?

【问题讨论】:

您似乎已经有一个涵盖所有 4 列的索引。对吗? 请提供样本数据和期望的结果。 您应该查看并提供查询的解释计划和实际执行时间。既然你问了一个优化问题,我预计查询时间太长了。第一个问题是为什么。知道了这一点,接下来该做什么了。 【参考方案1】:

我建议在加入之前而不是之后提取 distinct 值:

WITH r as (
      SELECT DISTINCT the_transaction_id, sport_label, family_label, item_label
      FROM txn_raw
     )
SELECT a.sport_label as sport_label_a, 
       a.family_label as family_label_a, 
       a.dsm_label as dsm_label_a, 
       b.sport_label as sport_label_b, 
       b.family_label as family_label_b, 
       b.dsm_label as dsm_label_b, 
       COUNT(*) as txn_ab
FROM r a JOIN 
     r b 
     ON a.the_transaction_id = b.the_transaction_id AND
        a.sport_label <> b.sport_label AND
        a.family_label <> b.family_label AND
        a.item_label <> b.item_label
GROUP BY 1,2,3,4,5,6;

我还希望您想要的实际 JOIN 条件是:

FROM r a JOIN 
     r b 
     ON a.the_transaction_id = b.the_transaction_id AND
        NOT (a.sport_label = b.sport_label AND
             a.family_label = b.family_label AND
             a.item_label = b.item_label
            )

那是。 . .任何一列都不同,而不是所有列。

【讨论】:

谢谢!我可以知道为什么最好先做 distinct 的原因吗? @LouisLaw 。 . .防止行的扩散,这只会减慢后续处理。

以上是关于如何优化与自身连接表的红移查询?的主要内容,如果未能解决你的问题,请参考以下文章

Python/SQLAlchemy:如何将巨大的红移表保存到 CSV?

您如何优化连接自身并执行“自定义”分组的 MySQL 查询?

带有子查询语法错误的红移更新查询

带变量的红移计数

如果您更改用户的红移密码,该用户的任何预先存在的连接是不是仍然有效?

如何使用 LIMIT syntx 优化具有 17 个连接表的复杂查询并限制每个连接的数据