Mysql order by -id vs order by id desc
Я хочу получить последние 10 строк из таблицы из 1 строки.
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`updated_date` datetime NOT NULL,
PRIMARY KEY (`id`)
)
Один из способов сделать это -
select * from test order by -id limit 10;
**10 rows in set (0.14 sec)**
Другой способ сделать это -
select * from test order by id desc limit 10;
**10 rows in set (0.00 sec)**
Итак, я сделал "EXPLAIN" в этих запросах -
Вот результат для запроса, в котором я использую "order by desc"
EXPLAIN select * from test order by id desc limit 10;
![enter image description here]()
И вот результат для запроса, где я использую 'order by -id'
EXPLAIN select * from test order by -id limit 10;
![enter image description here]()
Я думал, что это будет так же, но, похоже, есть различия в плане выполнения.
Ответы
Ответ 1
Вы используете ORDER BY с выражением, которое включает термины, отличные от имени столбца:
SELECT * FROM t1 ORDER BY ABS(key);
SELECT * FROM t1 ORDER BY -key;
Вы индексируете только префикс столбца, указанного в предложении ORDER BY. В этом случае индекс не может использоваться для полного разрешения порядка сортировки. Например, если у вас есть столбец CHAR (20), но индексируйте только первые 10 байтов, индекс не может отличить значения от 10-го байта, и потребуется файл filesort.
Тип используемого индекса таблицы не хранит строки в порядке. Например, это верно для индекса HASH в таблице MEMORY.
Пожалуйста, перейдите по этой ссылке: http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html
Ответ 2
RDBMS используют эвристику для расчета плана выполнения, они не всегда могут определить семантическую эквивалентность двух операторов, поскольку это слишком сложная задача (с точки зрения теоретической и практической сложности).
Таким образом, MySQL не может использовать индекс, так как у вас нет индекса на "-id", который является настраиваемой функцией, применяемой к полю "id". Кажется тривиальным, но РСУБД должны минимизировать время, необходимое для расчета планов, поэтому они застревают с простыми проблемами.
Когда оптимизация не может быть найдена для запроса (т.е. с использованием индекса), система возвращается к реализации, которая работает в любом случае: сканирование полной таблицы.
Ответ 3
Как вы можете видеть в результатах объяснения,
1: order by id
MySQL использует индексирование на id
. Таким образом, ему нужно перебирать строки 10, поскольку они уже проиндексированы. А также в этом случае MySQL не нужно использовать алгоритм filesort
, поскольку он уже проиндексирован.
2: order by -id
MySQL не, используя индексирование на id
. Поэтому для получения ожидаемых результатов необходимо выполнить итерацию всех строк (например, 455952). В этом случае MySQL должен использовать алгоритм filesort
, поскольку id
не индексируется. Так что, очевидно, потребуется больше времени:)