Комментарии 17
Казалось бы «база», но всегда полезно о ней напомнить.
А может есть решение как лучше оптимизировать запросы через ORM Django?
Насчет offset очень точно, реальная проблема на больших данных
keyset pagination спасает и супер прибавляет производительности)
WHERE user_id = 54821 и помог индекс по user_id? Да не может быть!
Кейс 3. JOIN, который создавал бомбежку всех строк
Что-то вы тут напахали. Исходный и конечный запросы ну даже близко не стояли...
Индекс должен соответствовать запросу
Совет в таком виде - безусловно вредный. Он звучит как предложение на каждый запрос создавать оптимальный для него индекс. Зарастёте индексами! Продумайте получше формулировку.
Как я указал в другом комментарии, приходится извиваться нестандартными способами, которые работают...
Ваш первый запрос в третьем кейсе решает задачу получения детализации со всей связанной информацией. Вместо это вы во втором запросе получаете агрегированные данные, и не получаете часть связанной информации. То есть вы, может, и извивались, но тем не менее начальную задачу вы НЕ РЕШИЛИ, вы вместо неё решили совсем иную задачу. Такой подход не просто странен - его как-то вообще невозможно понять. Программист говорит заказчику "Тебе это не надо, я тебе вместо этого сделаю совсем другое, оно тебе больше надо" - ну смешно же...
Уж если вы взяли на себя смелость и изменили поставленную вам задачу, то просто необходимо подробно обосновать, почему это сделано, и почему такой результат был принят. Причём ответ типа "так оптимальнее и быстрее работает" - заведомо не подходит.
ctrl+enter почему-то не срабатывает, поэтому отправлю так
У пользователя есть 20 заказов, 20 платежей и 10 отзывов. Рузельтат 20 × 20 × 10 = 4000 строк.
Проблематика понятная, но пример выбран надуманный, а предлагаемое решение по сути представляет собой решение какой-то другой задачи - просто написан совершенно иной запрос.
Если связь между таблицами разумная и, как показано ниже в решении, orders 1:M payments, то и при обсуждении исходной ситуации умножать 20 платежей на 20 заказов некорректно. В такой схеме и при таком запросе, если платежей 20, то и в результате будет всего 20 строк.
Джойн на отзывы действительно исполнен криво и было бы здорово, если бы в целом пример был додуман до осмысленного и в предлагаемом решении такое соединение бы тоже присутствовало, но с устранением проблемы. А про этот джойн в конце почему-то совсем забыли - и стало хорошо! Как говорится, я таких примеров много могу придумать. А обещали делиться реальным опытом...
Ну и вначале мы почему-то хотели получить все строки, какие найдутся, страдали от "4000 строк", а потом нас внезапно устроил агрегат по строке на заказ - это просто неудачно построенный пример, где для поиска способа устранить конкретную проблему совершается ход конём в полностью иное решение, под другую гипотетическую установку. Не надо так. К слову, если изначально платежей было 20, потому что по одному на заказ, то де-факто по данному конкретному пользователю число строк в итоге не изменится (неудачно выбранные вводные).
"Рузельтат ", "для лучше оптимизации" - спелчек.
Create index без concurrently
Analyze после создания индекса запускался?
Какие параметры СУБД использовать для столь мощного железа?
Вы можете использовать offset хоть на несколько миллионов строк, если вам не нужно поддерживать огромное кол-во сортировок.
SELECT *
FROM orders
WHERE user_id IN (
SELECT user_id
FROM orders
WHERE %(any_conditions_for_filters)
ORDER BY created_at DESC
OFFSET 120
LIMIT 20;
)
ORDER BY created_at DESC
Мы подразумеваем что user_id - это первичный ключ, либо просто имеет индекс.
В этом случае OFFSET будет почти незаметен. Вы отфильтровываете уже нужные id, которые хранятся в индексной таблице и не заставляете БД вычитывать все строки данных с диска для OFFSET
Спасибо, Кэп!
Если вы ещё для себя откроете составные индексы - вы откроете Америку! И обязательно напишите об этом статью! Поржем хоть ещё раз )
А нельзя было поставить тулзку какую-нибудь чтобы она это все нашла автоматом? Вроде примеры все тривиальные, в век AI все такое должно решаться, гугл сходу находит pganalyze, правда платный

Как мы ускорили SQL-запросы: реальные кейсы оптимизации PostgreSQL