Порядок строк MySQL для " SELECT * FROM table name;"

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

SELECT * FROM table_name;

обратите внимание, что нет ORDER BY статья дается.

мой вопрос:

дает ли MySQL какие-либо гарантии, в каком порядке будут даны строки результирующего набора? В частности, могу ли я предположить, что строки будут возвращены в порядке вставки (это тот же порядок, в котором строки были вставлены в таблицу)? Почему? Почему бы и нет?

предположить следующее структура таблицы:

CREATE TABLE table_name (
  foo1 mediumint(8) unsigned NOT NULL default '0',
  foo2 mediumint(8) unsigned NOT NULL default '0',
  foo3 mediumint(8) unsigned NOT NULL default '0',
  foo4 mediumint(8) unsigned NOT NULL default '0',
  UNIQUE KEY (foo1, foo2)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

6 ответов


нет, нет никаких гарантий. Если вы не укажете порядок с помощью 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 были вставлены в эти пробелы в обратном порядке, заполняя их с конца назад.

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


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


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

иногда 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 (и большинство / все движки СУБД) попытаются получить данные так же, как это хранится и как можно быстрее.


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

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

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

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


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


результаты в mysql 5.6 не выбраны по умолчанию в порядке вставки, вы можете делать обновления и т. д., И он возвращает запрос в любом порядке, который ему нравится