Не уверен, что это вам сильно поможет. Есть довольно странное предложение WHERE:
WHERE if(T1.trxn_id is null, 'NULL', T1.trxn_id) = if(T5.acct_trxn_id is null, 'NULL', T5.acct_trxn_id)
Это, вероятно, для объединения NULL
с нормальными значениями. Тогда это не работает, потому что
Прежде всего, условие соединения - T5 ON T1.trxn_id = T5.acct_trxn_id
, это означает, что NULL не объединяются, затем WHERE
работает как фильтр после объединения. Если T5
не присоединено, то T5.acct_trxn_id преобразуется в строку 'NULL' в WHERE и сравнивается со значением NOT NULL T1.trxn_id и, скорее всего, отфильтровывается, в этом случае работает как INNER JOIN. Если это происходит, T1.trxn_id имеет значение NULL (управляющая таблица), он преобразуется в строку 'NULL' и сравнивается со всегда строкой 'NULL' (потому что в любом случае не присоединяется согласно предложению ON), и такая строка пропускается (хотя я не проверял ее, хотя ). Логика выглядит странно, и я думаю, что она не работает так, как задумано, или конвертирована в INNER. Если вы хотите объединить все, включая NULL, переместите это WHERE в предложение JOIN ON.
Если имеется много строк с NULL, то объединение с NULL с использованием подстановки со строкой 'NULL' умножит строки и приведет к дублированию.
На самом деле, при расследовании плохой работы JOIN, проверьте две вещи:
- Ключи объединения не дублируются, или ожидается дублирование
- Ключи соединения (а также разбиение по столбцам в row_number) не перекошены, см. Это: https://stackoverflow.com/a/53333652/2700344 и это: https://stackoverflow.com/a/51061613/2700344
Если все выглядит хорошо, тогда настройте правильный параллелизм редуктора, уменьшите hive.exec.reducers.bytes.per.reducer
, чтобы запустить больше редукторов
Также максимально уменьшите DT_LKP
, даже если вы знаете, что он содержит некоторые даты, которые определенно не являются / не должны быть в действительности таблицами, используйте CTE для его фильтрации, если это возможно.
Также немного упростите логику (это не улучшит производительность, но упростит код).
Дело в выборе:
when T1.trxn_id is not null and T5.acct_trxn_id is not null and T2.crt_ts >= T5.crt_ts then T2.crt_ts
when T1.trxn_id is not null and T5.acct_trxn_id is not null and T2.crt_ts < T5.crt_ts then T5.crt_ts
<=>
else greatest(T2.trxn_id,T5.crt_ts)
Если T5.crt_ts равен нулю, ваш оператор case вернет ноль, great () также вернет ноль
Упрощенный оператор CASE в row_number:
case when case when (T1.trxn_id is null) or (T5.acct_trxn_id is null) then T2.crt_ts
else greatest(T2.trxn_id,T5.crt_ts)
end
Также это: if(T1.trxn_id is null, 'NULL', T1.trxn_id)
<=> NVL(T1.trxn_id,'NULL')
Конечно, это только предложения, я их не проверял