«Почему» : подзапрос по определению возвращает неупорядоченный набор строк.Оптимизатор только недавно начал использовать этот пункт в Стандарте.При этом он отбрасывает ORDER BY
(если не существует LIMIT
; см. План A).Порядок, который вы видели, был просто совпадением, основанным, возможно, на индексе, который использовался для удовлетворения WHERE
.Чтобы правильно отсортировать результаты, вы должны применить некоторое упорядочение после этого (см. Планы B).
Другая недавняя оптимизация ... Ранее UNION
всегда подавал результаты из каждого подзапроса ввременная таблица.Теперь, в случае UNION ALL
(и некоторых других ограничений), он может передавать результаты непосредственно клиенту.(Тем не менее, мои предложенные планы B и C по-прежнему нуждаются в временном интервале для выполнения ORDER BY
.)
План A - это помеха, которую может сработать:
(SELECT * FROM table ORDER BY table.field DESC, table.timestamp DESC
LIMIT 9999999)
UNION ALL
(SELECT * FROM table ORDER BY table.timestamp DESC
LIMIT 9999999)
План B может работать в зависимости от того, может ли ORDER BY
соответствовать данным:
(SELECT * FROM table)
UNION ALL
(SELECT * FROM table)
ORDER BY table.field DESC, table.timestamp DESC
План C является попыткой обобщить План B:
(SELECT *, 1 AS seq1, table.field AS seq2 FROM table)
UNION ALL
(SELECT *, 2 AS seq1, 0 AS seq2 FROM table)
ORDER BY seq1, -- to get the first SELECT first
seq2 DESC, -- unclear what your intent was with table.field
timestamp DESC
Итог .Чтобы получить заказ, вы должны явно указать ORDER BY
.(В настоящее время вы зависите от UNION
работ, выполняемых последовательно. Некоторые день, UNIONs
могут выполняться параллельно.)