Вы строите виджет «последние события» и используете ORDER BY created_at DESC LIMIT 100. В created_at много одинаковых значений, и пользователи жалуются, что список «дрожит». Какое изменение лучше всего повышает стабильность результата, не ломая идею оптимизации через индекс?
AУбрать
ORDER BY и сортировать результат на стороне приложения, чтобы база не тратила ресурсы на упорядочивание строк.BЗаменить
LIMIT 100 на FETCH FIRST 100 ROWS WITH TIES, чтобы при совпадении значений возвращались все связанные строки.CДобавить
ORDER BY random() как вторичный ключ, чтобы каждый запрос возвращал непредсказуемо случайный, но стабильный для пользователя порядок.DСделать порядок детерминированным, например
ORDER BY created_at DESC, event_id DESC LIMIT 100 (и при необходимости иметь индекс, который поддерживает такой порядок).Правильный ответ. Для стабильного
LIMIT нужен детерминированный ORDER BY с tie-breaker.Разбор
Если сортировка идёт только по created_at, то строки с одинаковым временем могут возвращаться в разном порядке в разных запусках — SQL это не запрещает. Добавление второго ключа (например, event_id) делает порядок однозначным. При хорошем индексе по (created_at, event_id) или похожем порядке оптимизация через чтение из индекса может сохраниться.
Проверь себя · 1/3разбор после ответа
В выводе
EXPLAIN вы видите оценку cost=0.00..431.00. Какой вывод аналитик может сделать безопасно?Ещё вопросы по теме «EXPLAIN и оптимизация»
- Вы хотите добавить новый запрос в дашборд и боитесь, что он сильно нагрузит базу, потому что таблица `events` очень большая. Что даёт запуск `EXPLAIN` для этого запроса?
- В выводе `EXPLAIN` вы видите узел `Seq Scan on orders`. Что это обычно означает в плане выполнения запроса?
- В плане `EXPLAIN` для запроса по пользователю вы видите проход по индексу `orders_user_id_idx` для таблицы заказов. Какой вывод наиболее корректен?
- На большой таблице `events` запрос `SELECT * FROM events ORDER BY created_at DESC LIMIT 100` неожиданно работает быстро. Какое объяснение наиболее вероятно при наличии индекса по `created_at`?
- Есть индекс по `orders.created_at`, но `EXPLAIN` для фильтра `WHERE date(created_at) = current_date` показывает `Seq Scan`. Почему это часто происходит?
- Все вопросы по «EXPLAIN и оптимизация» →