Вы ожидаете, что LIMIT 10 всегда означает «обработать только 10 строк». Но EXPLAIN для запроса SELECT * FROM events WHERE user_id = 42 ORDER BY created_at DESC LIMIT 10 показывает Sort по большому количеству строк перед Limit. Что это означает?
A
LIMIT 10 игнорируется планировщиком, и база возвращает все строки таблицы независимо от ограничения в запросеBБаза обязана сначала вернуть все строки клиенту, а потом приложение само применяет
LIMIT 10 уже на своей сторонеC
EXPLAIN запрещено использовать вместе с ORDER BY, поэтому план показывает заведомо некорректную картину выполненияDЧтобы выбрать первые строки в нужном порядке, базе может понадобиться обработать большой набор данных, если нет подходящего индекса
Правильный ответ.
LIMIT экономит работу только если план может рано остановиться, например через индекс под ORDER BY.Разбор
Когда план включает Sort, базе всё равно нужно рассмотреть большой набор строк, чтобы понять, какие из них первые по ORDER BY. В этом случае LIMIT лишь сокращает финальный вывод, но не избавляет от основной работы. Подходящий индекс по (user_id, created_at DESC) или более селективный фильтр позволяют плану рано остановиться и сделать LIMIT реально полезным. Утверждения про игнорирование LIMIT, обязательную передачу всех строк клиенту или запрет EXPLAIN с ORDER BY неверны.
Проверь себя · 1/3разбор после ответа
Как удобнее интерпретировать дерево
EXPLAIN, чтобы понять, откуда берутся строки и где тратятся ресурсы запроса?Ещё вопросы по теме «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 и оптимизация» →