Оптимизация SQL запросов
Общие правила:
1️⃣ База базовая - минимизация использования DISTINCT, ORDER BY, UNION. Если нет необходимости использовать данные конструкции - не используем! Будет выполняться сортировка, а на больших данных это оочень ресурсозатратно!
2️⃣ Звездочка в select - зло. Выбираем только необходимые поля!
Неправильно:
SELECT * FROM SALES;
Правильно:
SELECT SALE_ID, SALE_DT FROM SALES;
3️⃣ Уметь смотреть план запроса и иметь понятие об основных способах соединения таблиц
4️⃣ Если разработка идет на синтетике или на не полном объеме, всегда запрашивать боевые цифры и исходя из этого принимать решение о датафиксах, группировках, джойнах. Если же код новый и сущности еще только формируются, то предполагаемые объемы надо запрашивать у аналитика – хотя бы порядок строк – сотни тысяч/миллионы/сотни млн
5️⃣ Не писать одно тело селекта с парой-тройкой десятков таблиц. Логические куски помещать в with – так проще управлять.
6️⃣Не бояться бить большие запросы на 2-3 сессии:
➖ Не должно быть, например, 80 джойнов, из которых половина это миллионы строк. Попробовать как-то логически поделить например на 2 куска, и чтобы не использовать разные with из первой части во второй.
➖ Очень большой код, например, 3тысячи строк читать, сопровождать, понимать что случилось довольно затруднительно – есть смысл разбивать на логические части.
7️⃣ Понимать, когда и для чего использовать хинты. Помнить, что хинты – это костыли. Не лепить в каждой строчке все что возможно.
8️⃣ Если запрос падает на нехватке темпа, то
➖ замножение записей (неправильное условие соединения ON или связь один ко многим, либо многие ко многим)
➖ кривой план/неправильная последовательность соединения множеств
➖ отправка на параллельные исполнители в широковещательном режиме (broadcast) огромных объёмов данных. Можно поправить хинтом
➖ Для тестовой среды: проверить объём темп, если число файлов не совпадает/сильно меньше, чем на бою – сделать сравнимым, если возможно .
9️⃣ Никогда не использовать в условиях соединения ON вложенные селекты
1️⃣0️⃣ Никогда не использовать в списке полей select-a, определяемых с помощью функций, вложенные селекты.
Иными словами не должно быть конструкций вида:
select t.f1, t.f2,
case when select [] then … end f3
from table t
В списке полей должны быть только поля и всевозможные необходимые функции, а селект нужно приджоинить к общей выборке.
Аналогично и для условий where – не должно быть вложенных селектов внутри функций - это приводит к возникновению ненужных циклов.
➖➖➖➖➖➖➖➖➖➖➖➖
Предлагайте свои правила и фишки по оптимизации.
Давно хотел сделать подобный посту 💅
Жду реакции и репосты😊⬇️
it пингвин | data engineer 🐧
#sql #оптимизация
Общие правила:
1️⃣ База базовая - минимизация использования DISTINCT, ORDER BY, UNION. Если нет необходимости использовать данные конструкции - не используем! Будет выполняться сортировка, а на больших данных это оочень ресурсозатратно!
2️⃣ Звездочка в select - зло. Выбираем только необходимые поля!
Неправильно:
SELECT * FROM SALES;
Правильно:
SELECT SALE_ID, SALE_DT FROM SALES;
3️⃣ Уметь смотреть план запроса и иметь понятие об основных способах соединения таблиц
4️⃣ Если разработка идет на синтетике или на не полном объеме, всегда запрашивать боевые цифры и исходя из этого принимать решение о датафиксах, группировках, джойнах. Если же код новый и сущности еще только формируются, то предполагаемые объемы надо запрашивать у аналитика – хотя бы порядок строк – сотни тысяч/миллионы/сотни млн
5️⃣ Не писать одно тело селекта с парой-тройкой десятков таблиц. Логические куски помещать в with – так проще управлять.
6️⃣Не бояться бить большие запросы на 2-3 сессии:
➖ Не должно быть, например, 80 джойнов, из которых половина это миллионы строк. Попробовать как-то логически поделить например на 2 куска, и чтобы не использовать разные with из первой части во второй.
➖ Очень большой код, например, 3тысячи строк читать, сопровождать, понимать что случилось довольно затруднительно – есть смысл разбивать на логические части.
7️⃣ Понимать, когда и для чего использовать хинты. Помнить, что хинты – это костыли. Не лепить в каждой строчке все что возможно.
8️⃣ Если запрос падает на нехватке темпа, то
➖ замножение записей (неправильное условие соединения ON или связь один ко многим, либо многие ко многим)
➖ кривой план/неправильная последовательность соединения множеств
➖ отправка на параллельные исполнители в широковещательном режиме (broadcast) огромных объёмов данных. Можно поправить хинтом
➖ Для тестовой среды: проверить объём темп, если число файлов не совпадает/сильно меньше, чем на бою – сделать сравнимым, если возможно .
9️⃣ Никогда не использовать в условиях соединения ON вложенные селекты
1️⃣0️⃣ Никогда не использовать в списке полей select-a, определяемых с помощью функций, вложенные селекты.
Иными словами не должно быть конструкций вида:
select t.f1, t.f2,
case when select [] then … end f3
from table t
В списке полей должны быть только поля и всевозможные необходимые функции, а селект нужно приджоинить к общей выборке.
Аналогично и для условий where – не должно быть вложенных селектов внутри функций - это приводит к возникновению ненужных циклов.
➖➖➖➖➖➖➖➖➖➖➖➖
Предлагайте свои правила и фишки по оптимизации.
Давно хотел сделать подобный посту 💅
Жду реакции и репосты😊⬇️
it пингвин | data engineer 🐧
#sql #оптимизация