Redshift SQL JOIN ведет себя по-разному для одного идентификатора и отличается, когда у нас есть более одного идентификатора в предикате? - PullRequest
0 голосов
/ 30 мая 2019

Я не могу поделиться данными и деталями таблицы, поэтому, чтобы повторить проблему, вот тестовые таблицы с образцами данных.Таблица 'table1' содержит 14 строк с 10 уникальными строками для значений 'column1' 'id1' и 12 строк с 8 уникальными строками для идентификатора 'id2'.«table2» имеет 1 строку для значений «column1» «id1» и «id2».

ПРИМЕЧАНИЕ. Проблема заключается в том, что не воспроизводится этими тестовыми таблицами.Фактически, после воссоздания реальных таблиц, где я вижу эту проблему, я получаю правильный результат соединения.На данный момент, я считаю, что что-то изменилось за кулисами в красном смещении, из-за этого я вижу эту проблему.Я обновлю, как только услышу больше.

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 идентификаторами дает по 1 строке на каждое значение column1, то есть «id1» и «id2».Здесь я ожидаю 10 строк для 'id1' и 8 строк для 'id2'.

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

CASE 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 и 4, чтобы избежать путаницы.

1 Ответ

0 голосов
/ 04 июня 2019

Во-первых, было неправильно иметь ограничение первичного ключа для таблицы, где мы знали, что не будет уникальных значений для этого поля первичного ключа, даже если мы думали, что красное смещение не применяет его таким же образом для внешнего или уникального ключа ограничения.

Во время ETL необходимо убедиться, что данные, которые мы загружаем в столбец первичного ключа, уникальны, иначе мы не должны определять такой столбец как первичный ключ.

Если мы просто перейдем к запросу типа (trim () в столбце первичного ключа), он вернет правильные результаты, потому что в этом случае мы заставим оптимизатор игнорировать первичный ключ.

Причина, по которой мы не видели эту проблему раньше, потому что оптимизатор запросов не учитывал первичный ключ для рассмотрения в моем случае 1.

В последнее время в одном из обновлений красного смещения в конце марта оптимизатор запросов начал использовать преимущества первичного ключа, чтобы повысить производительность запросов после того, как проблема началась.

Итак, в моем случае решение состоит в том, чтобы удалить ограничение первичного ключа для таблицы, и запрос остается прежним.

...