首页 > 解决方案 > Redshift SQL JOIN 对于一个 ID 的行为是不同的,并且当我们在谓词中有多个 ID 时会有所不同?

问题描述

我无法共享数据和表格详细信息,因此为了复制问题,这里是带有示例数据的测试表。表“table1”共有 14 行,其中 10 个唯一行用于“column1”值“id1”,共有 12 行,8 个唯一行用于 ID“id2”。“table2”对于“column1”值“id1”和“id2”各有 1 行。

注意:这些测试表无法重现该问题。事实上,在我看到这个问题的实际表重新创建之后,我得到了正确的连接结果。目前,我认为红移的幕后发生了一些变化,因此我看到了这个问题。一旦我听到更多,我会更新。

CREATE TABLE IF NOT EXISTS table1 (
column1 varchar(255) encode lzo,
t1column2 varchar(255) encode lzo,
t1column3 varchar(255) encode lzo,

PRIMARY KEY(column1))
distkey(column1)
sortkey(column1);

COMMIT;

----------------------------------

CREATE TABLE IF NOT EXISTS table2 (
column1 varchar(255) encode lzo,
t2column2 varchar(255) encode lzo,
t2column3 varchar(255) encode lzo,
);

COMMIT;

----------------------------------

insert into table1 values
('id1', '0', 'a'),
('id1', '0', 'a'),
('id1', '0', 'a'),
('id1', '0', 'a'),
('id1', '1', 'a'),
('id1', '1', 'a'),
('id1', '2', 'a'),
('id1', '3', 'a'),
('id1', '4', 'a'),
('id1', '5', 'a'),
('id1', '6', 'a'),
('id1', '7', 'a'),
('id1', '8', 'a'),
('id1', '9', 'a'),
('id2', '0', 'a'),
('id2', '0', 'a'),
('id2', '1', 'a'),
('id2', '2', 'a'),
('id2', '3', 'a'),
('id2', '4', 'a'),
('id2', '5', 'a'),
('id2', '6', 'a'),
('id2', '7', 'a'),
('id2', '7', 'a'),
('id2', '7', 'a'),
('id2', '7', 'a');

-------------------------

insert into table2 values
('id1', null, 'pqr'),
('id2', null, 'xyz'),

案例 1:具有 2 个 id 的查询每列 1 值给出 1 行,即“id1”和“id2”。在这里,我预计 'id1' 有 10 行,'id2' 有 8 行。

select distinct t1.column1, t1.t1column2, t1.t1column3, t2.t2column2, t2.t2column3 
from table1 t1
join table2 t2 
on t1.column1=t2.column1
where t1.column1 IN ('id1', 'id2');

案例 2:当仅使用 1 个值 'id1' 执行相同的查询时,会按预期提供正确的 10 个唯一行。

select distinct t1.column1, t1.t1column2, t1.t1column3, t2.t2column2, t2.t2column3 
from table1 t1
join table2 t2 
on t1.column1=t2.column1
where t1.column1 IN ('id1');

删除了 CASE 3 和 CASE 4 以避免混淆。

标签: sqljoinamazon-redshift

解决方案


首先,在我们知道该主键字段不会有唯一值的表上设置主键约束是错误的,即使我们认为 redshift 不会以相同的方式强制外键或唯一键约束。

在 ETL 期间,需要确保我们加载到主键列中的数据是唯一的,否则我们不应该将这样的列定义为主键。

如果我们只是更改为 (trim() on primary key column) 之类的查询,它将返回正确的结果,因为在这种情况下,我们将强制优化器忽略主键。

我们之前没有看到这个问题的原因是查询优化器在我的案例 1 中没有考虑主键。

最近,在 3 月下旬某个时间的一次红移更新中,查询优化器开始更多地利用主键来提高查询性能,之后问题就开始了。

因此,在我的情况下,解决方案是删除表上的主键约束,并且查询保持不变。


推荐阅读