Подтвердить что ты не робот

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

Я думал, что это будет так же, но, похоже, есть различия в плане выполнения.

4b9b3361

Ответ 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 не индексируется. Так что, очевидно, потребуется больше времени:)