Каков порядок строк MySQL для «SELECT * FROM table_name;»?

15

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

SELECT * FROM table_name;

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

Мой вопрос:

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

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

  • 0
    Дубликат: stackoverflow.com/questions/1793147/…
  • 1
    OMG Ponies: Спасибо за ссылку - она содержит несколько очень полезных ответов. Я не считаю этот вопрос точной копией, поскольку он носит очень общий характер, в то время как мой вопрос специфичен для MySQL.
Показать ещё 1 комментарий
Теги:
select
order
sql-order-by

6 ответов

28
Лучший ответ

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

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

  • 0
    Какая версия вашего MySQL. Моя версия СУБД mysql - 5.6.16, для osx10.9 (x86_64). Результат сильно отличается от вашего.
  • 0
    Нажмите 7ktwa5.com1.z0.glb.clouddn.com/the_sort_of_mysql.png для получения более подробной информации.
Показать ещё 4 комментария
5

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

  • 0
    Результаты определенно не будут в этих порядках, если вы делаете удаления, а также вставки в эти таблицы. У @BillKarwin есть хорошее объяснение того, почему выше.
4

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

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

2

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

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

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

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

  • 2
    Annnnd ... сразу после этого: «Хотя записи обычно извлекаются в том порядке, в котором они вставлены в базу данных, вы не можете полагаться на сохранение определенного порядка». Вы никогда не можете полагаться на это, потому что, как только страница данных заполнена, строки перемещаются.
  • 0
    Это правда, я согласен с тем, что без приказа вы не уверены, что получите обратно.
1

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

0

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню