ORDER BY
Только ORDER BY гарантирует порядок строк результата.
SELECT id, user_id, created_at
FROM orders
ORDER BY created_at DESC, id DESC;id добавлен как уникальный tie-breaker. Без него строки с одинаковым created_at могут менять взаимный порядок, особенно между страницами.
NULL
Положение NULL зависит от СУБД и направления сортировки. Где поддерживается, намерение задают явно:
ORDER BY shipped_at DESC NULLS LASTДля переносимости можно использовать CASE, но это может повлиять на индекс и план.
Индекс и сортировка
CREATE INDEX idx_orders_created_id
ON orders (created_at DESC, id DESC);Индекс может отдать строки в нужном порядке и убрать отдельную сортировку, если фильтр и направление совместимы. Но чтение большой доли таблицы или несовместимый префикс могут сделать другой план дешевле.
Выражения и псевдонимы
SELECT user_id, SUM(total) AS amount
FROM orders
GROUP BY user_id
ORDER BY amount DESC, user_id;Псевдоним результата обычно разрешен в ORDER BY, потому что сортировка логически идет после SELECT.
Ловушки
- Порядок строк в таблице, индексе или подзапросе не является контрактом внешнего запроса.
- Сортировка строк зависит от collation.
- Большая сортировка может выйти во временные файлы.
ORDER BY RANDOM()часто требует работу со всем набором.
Связано: Оператор LIMIT, Индексы SQL, SQL оценка производительности.
Вопросы
Почему нужен уникальный tie-breaker? Для детерминированного порядка равных ключей и стабильной пагинации.
Гарантирует ли primary key порядок без ORDER BY? Нет.
Когда индекс убирает сортировку? Когда его порядок соответствует фильтру и требуемому ORDER BY.
Где окажется NULL? Зависит от СУБД; важное поведение задают явно.