Redshift SQL JOIN对于一个ID的行为会有所不同,并且在谓词中有多个ID时会有所不同?

时间:2019-05-30 16:21:06

标签: sql join amazon-redshift

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

注意:这些测试表无法重现。实际上,在重现我看到此问题的实际表之后,我得到了正确的联接结果。 目前,我认为在Redshift的幕后发生了一些变化,因此我看到了这个问题。我会在听到更多消息后进行更新。

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

PRIMARY KEY(id))
distkey(id)
sortkey(id);

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进行查询时,每个column1值(即'id1'和'id2')每个都有1行。

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');

情况3: -按

的顺序为给定的column1值正确给出10和8个唯一行
select temp.column1, temp.t1column2, temp.t1column3, t2.t2column2, t2.t2column3
from table2 t2
join 
(select distinct t1.column1, t1.t1column2, t1.t1column3 from table1 t1
where t1.column1 IN ('id1', 'id2')) temp
on temp.column1=t2.column1;

案例4: -与CASE 3相同的查询,但只有1个值'id1',给出了所有行(14)而不是10。这包括重复项。

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

1 个答案:

答案 0 :(得分:0)

首先在表上具有主键约束是错误的,因为我们认为该主键字段将没有唯一值,即使我们认为redshift不会以相同的方式对外键或唯一键强制执行约束。

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

如果我们只更改查询(主键列上的trim()),它将返回正确的结果,因为在这种情况下,我们将迫使优化器忽略主键。

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

最近,在3月下旬的某个Redshift更新中,查询优化器已开始利用主键的更多优势,以提高问题开始后的查询性能。

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