Куратор раздела
Правила хорошего тона
-
Используйте только те колонки, которые вам необходимы. Не нужно в продовый запрос тыкать “SELECT *”, в 90% всех таблиц в ГП используется колоночное хранение(каждая колонка находится в отдельном файле), это в свою очередь ведет к поиску всех колонок.
-
Изучайте DDL таблиц перед тем как с ними работать. Обращайте внимание по какким полям таблица рапределена и партицирована. В фильтрах старайтесь указывать поля партицирования, чтобы уменьшить кол-во считываемых данных.
-
Чаще всего партиции строят на несколько месяцев-лет вперед, поэтому при фильтрации по дате партицирования обязательно ставте границу до сегодняшнего дня, в противном случае БД будет заходить в партиции, в которых нет данных.
where dt > '2025-05-01' and dt < current_timestamp()
where date between '2025-05-01' and current_date()- Не делайте бессмысленных преобразований типов данных.
where date_trunc('month', dt)::date < current_date -- здесь и так округление до 00:00:00-
Не преобразуйте колонки, по которым парцированы или распредлены таблицы, это приведет к новому перераспределению данных, а парции вообще использоваться не будут
-
Из фильтрации убирайте функции, они там не нужны. Если необходимо фильтрануться по пользовательской функции, находите ее текст(посмотреть скрипт можно тут и используйте только те условия, которые вам нужны, либо расчет выводите в отдельную темповую таблицу.
-
Не соединяйте таблицы не по ключам распределения. Старайтесь выводить данные таблицы в темповые, фильтровать их по максисуму, распределять по логике ваших дальнейших соединений.
-
Используйте предрасчитанные поля, так как нужно заново высчитывать значения поля
where dt + interval '3h' > curremt_timestamp - interval '7 day' -- левая чать не предрасчитана
where dt > curremt_timestamp - interval '7 day' - interval '3h' -- левая чать предрасчитана- Усли условие JOIN большое(3 и более условий) например
from t1
JOIN t2
ON t1.col1 = t2.col1 and
t1.col2 = t2.col2 and
t1.col3 = t2.col3 and
t1.col4 = t2.col4лучше вынесите таблицы в темповую таблицу, захешируйте значения(но обращаю внимание hash(null) дает заначение, поэтому либо отфильтруйте их либо воспользуйтесь CASE) иначе соединится не то что нужно
-
group byиpartition byделайте по полям дистрибуции -
В GreenPlum нет наследование алиасов, не нужно копировать 10 преобразований одно и того же поля, выведите все в отдельное СТЕ и уже работайте от туда
-
В JOIN не указывайте поля соединения через OR, старайтесь уйти от этого
-
небольшие таблицы можно делать в дистрибуцией по Replicated это позволит быстрее обрабатывать JOIN в запросах
-
Не используйте plpgsql функций в теле запроса, это замендляет работу запроса
Кейсы
Кейс 1: Уходи от OR в JOIN'ах
Есть запрос в котором втречается JOIN с 3мя условиями. Таблицы имеют большое кол-во строк.
SELECT ...
FROM _tmp_calc_cred AS cc
INNER JOIN _postback_api as pa
ON cc.request_external_id = pa.EXTERNAL_ID OR
cc.calculation_id = pa.EXTERNAL_ID OR
cc.request_id = pa.EXTERNAL_IDВо первых в данном случе стоит рапледелить таблицу _tmp_calc_cred по всем сегментам, так как в JOIN используется 3 разные колонки, а таблицу _postback_api по ключу EXTERNAL_ID, чтобы запрос выполнялся параллельно на разных сегментах.
Данный запрос стоит преобразовать к следующиму виду:
select ...
FROM alexd._tmp_CALCULATION_CREDIT AS cc
INNER JOIN alexd._postback_api as pa
ON cc.request_external_id = pa.EXTERNAL_ID
union all
select ...
FROM alexd._tmp_CALCULATION_CREDIT AS cc
INNER JOIN alexd._postback_api as pa
ON cc.calculation_id = pa.EXTERNAL_ID
union
select ...
FROM alexd._tmp_CALCULATION_CREDIT AS cc
INNER JOIN alexd._postback_api as pa
ON cc.request_id = pa.EXTERNAL_IDВ первом случае выберится физический вид JOIN'а - Nested Loop, 2й запрос хоть и больше, но выберится Hash JOIN. Здесь главное по отдельности запустить запросы и пприкинуть, какое максимальное кол-во строк может получиться в результате. Если строк в результате получается больше, чем в самих таблицах (произошел CROSS JOIN данных), то возможно 1й вариант будет выстрее!
