Что является порядком строк MySQL для “ВЫБОРА * ОТ table_name”;?

Предположите, что следующий запрос выпущен к базе данных MySQL:

SELECT * FROM table_name;

Обратите внимание что нет ORDER BY пункт дан.

Мой вопрос:

MySQL дает какие-либо гарантии, которому порядку будут даны строки набора результатов?

Строго говоря, я могу предположить, что строки будут возвращены в порядке вставки?, это - тот же порядок, в который строки были вставлены в таблицу.

17
задан Petter Friberg 25 January 2019 в 10:04
поделиться

5 ответов

Нет, нет никаких гарантий. Если вы не указываете порядок с помощью пункта ORDER BY, порядок полностью зависит от внутренних деталей реализации. Т.е. все, что наиболее удобно для движка СУБД.

На практике, строки могут быть возвращены в исходном порядке вставки (или, точнее, в порядке, в котором строки существуют в физическом хранилище), но вы не должны зависеть от этого. При портировании приложения на СУБД другого бренда, или даже при переходе на более новую версию MySQL, которая может реализовывать хранение по-другому, строки могут возвращаться в другом порядке.

Последнее справедливо для любой SQL-совместимой СУБД.


Вот демонстрация того, что я имею в виду под порядком существования строк в хранилище, в сравнении с порядком их создания:

CREATE TABLE foo (id SERIAL PRIMARY KEY, bar CHAR(10));

-- create rows with id 1 through 10
INSERT INTO foo (bar) VALUES
  ('testing'), ('testing'), ('testing'), ('testing'), ('testing'), 
  ('testing'), ('testing'), ('testing'), ('testing'), ('testing');

DELETE FROM foo WHERE id BETWEEN 4 AND 7;

+----+---------+
| id | bar     |
+----+---------+
|  1 | testing |
|  2 | testing |
|  3 | testing |
|  8 | testing |
|  9 | testing |
| 10 | testing |
+----+---------+

Итак, теперь у нас шесть строк. Хранилище на данный момент содержит промежуток между строками 3 и 8, оставшийся после удаления средних строк. Удаление строк не дефрагментирует эти пробелы.

-- create rows with id 11 through 20 
INSERT INTO foo (bar) VALUES
  ('testing'), ('testing'), ('testing'), ('testing'), ('testing'), 
  ('testing'), ('testing'), ('testing'), ('testing'), ('testing');

SELECT * FROM foo;

+----+---------+
| id | bar     |
+----+---------+
|  1 | testing |
|  2 | testing |
|  3 | testing |
| 14 | testing |
| 13 | testing |
| 12 | testing |
| 11 | testing |
|  8 | testing |
|  9 | testing |
| 10 | testing |
| 15 | testing |
| 16 | testing |
| 17 | testing |
| 18 | testing |
| 19 | testing |
| 20 | testing |
+----+---------+

Обратите внимание, как MySQL повторно использовал пробелы, открывавшиеся после удаления строк, перед добавлением новых строк в конец таблицы. Также обратите внимание, что строки с 11 по 14 были вставлены в эти пробелы в обратном порядке, заполняя их с конца таблицы в обратном порядке. Поэтому порядок хранения строк не является точно тем порядком, в который они были вставлены

.
29
ответ дан 30 November 2019 в 11:17
поделиться

Для этого потока , по умолчанию сортировка - порядок вставки для MyISAM, а для InnoDB - возрастание первичного ключа. Но я не думаю, что это гарантия, просто как это известно работает.

5
ответ дан 30 November 2019 в 11:17
поделиться

Нет, определенно нет. В зависимости от используемого движка базы данных (ISAM или InnoDB), структура таблицы будет в целом представлять собой некое b-дерево для более быстрого поиска по строкам. Это не имеет никакого отношения к порядку вставки, а скорее к тому, как БД строит индекс на основе первичного ключа (или, в случае отсутствия ключа, как хранится куча таблиц)

.
1
ответ дан 30 November 2019 в 11:17
поделиться

Нет, вы не можете.

Иногда MySQL будет выполнять селективные запросы с ключами, которые вы не ожидаете. Рассмотрим эту таблицу:

CREATE TABLE `user_permissions` (
  `permId` int(5) unsigned NOT NULL AUTO_INCREMENT,
  `permKey` varchar(16) NOT NULL,
  `permDesc` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`permId`),
  KEY `key_lookup` (`permKey`,`permId`,`permDesc`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

MySQL почти всегда будет использовать клавишу key_ lookup для выполнения любой операции селекции по этой таблице; так как permKey является первым полем, то оно обычно заканчивается "сортировкой" по этому ключу (который появляется в алфавитном порядке, но не совсем).

Без пункта ORDER BY MySQL (и большинство/все движки СУБД) будут пытаться получить данные точно так же, как они хранятся, и так же быстро, как это возможно.

.
4
ответ дан 30 November 2019 в 11:17
поделиться

Из Извлечение данных с помощью оператора MySQL SELECT Statement: оператор SELECT Statement

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

Да, согласно комментарию

Хотя записи, как правило, являются восстановленные в том порядке, в котором они вставляются в базу данных, вы не может полагаться на конкретный заказ сохранены. Если ваша база данных скопированный и восстановленный, или если техническое обслуживание осуществляется на база данных, MySQL может изменить порядок хранения записей внутри.

3
ответ дан 30 November 2019 в 11:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: