2010-07-29 1 views
2

У меня есть mysql db с таблицей «трудности» с несколькими записями. Если я действительно «выберите * от трудностей» я получить их обратно в порядке, они были добавлены, отсортированы по первичному ключу ID:Mysql: Порядок результатов с «select <fieldname> from» отличается на порядок от «select * from»

mysql> select * from difficulties; 
+----+-------+-----------+--------+----------+-----------+ 
| id | value | name  | letter | low_band | high_band | 
+----+-------+-----------+--------+----------+-----------+ 
| 1 |  1 | very_easy | VE  |  1 |   1 | 
| 2 |  2 | easy  | E  |  2 |   5 | 
| 3 |  3 | medium | M  |  6 |  10 | 
| 4 |  4 | hard  | H  |  11 |  12 | 
| 5 |  0 | na  | NA  |  0 |   0 | 
+----+-------+-----------+--------+----------+-----------+ 

Однако, если я «выберите имя из трудностей» я получить их обратно в другой порядок:

mysql> select name from difficulties; 
+-----------+ 
| name  | 
+-----------+ 
| easy  | 
| hard  | 
| medium | 
| na  | 
| very_easy | 
+-----------+ 

Мой вопрос: что определяет этот заказ? Есть ли какая-то логика? Это что-то вроде «того, как файлы, представляющие записи, попадают в файловую систему» ​​или что-то еще, что является случайным?

спасибо, Макс

ответ

4

Это правильно и по дизайну: , если вы не просите для сортировки, сервер не заморачиваться с сортировкой (сортировка может быть дорогостоящей операцией), и он вернется строки в любом порядке, который он считает нужным. Без запрошенного заказа способ упорядочивания записей может даже отличаться от одного запроса к другому (хотя это не слишком вероятно).

Порядок определенно не случайный - это как раз то, как строки выходят из запроса, и, как видите, даже незначительные изменения могут значительно изменить этот порядок. Этот «неопределенный» заказ зависит от реализации, непредсказуем и не следует полагаться.

Если вы хотите, чтобы элементы были заказаны, используйте предложение ORDER BY (это его назначение) - например.

SELECT name FROM difficulties ORDER BY name ASC; 

Это будет всегда возвращать результат отсортированный по имени в порядке возрастания. Или, если вы хотите, чтобы они отсортированы по первичному ключу, последние сверху, использование:

SELECT name FROM difficulties ORDER BY id DESC; 

Вы можете даже сортировать по функции - если вы на самом деле хотите случайного порядка, сделать это (предостережение: ужасное исполнение с великоватым таблицы):

SELECT name FROM difficulties ORDER BY RAND(); 

Для получения более подробной информации see this tutorial и the documentation.

+0

Спасибо Piskvor, что все имеет смысл. Я знаю о порядке, я просто интересовался тем, что происходило в этой ситуации. Я предполагаю, что я ошибочно предположил, что возвращение записей (или полей из записей) в том порядке, в котором записи появляются в таблице, будет самой легкой/дешевой вещью для dbms, и, следовательно, что бы она сделала, но у меня есть ничто не основывает это предположение на :) cheers, max –

+0

@Max Williams: Я бы предположил, что @ a1ex07 верен там с индексом покрытия (т. е. индексом в столбце 'name') - xe? Это заставило бы «просто прочитать, что индекс имеет» самую дешевую операцию при запросе только столбца «name», но не при запросе всех столбцов. См. это для более подробного объяснения: http://peter-zaitsev.livejournal.com/6949.html – Piskvor

-2

select name from difficulties должен возвращать значения в алфавитном порядке, так как это текстовое поле. И select * from difficulties вернется в числовом порядке, я верю. Dont держать меня в этом LOL

лучше всего сделать, это использовать ORDER BY, если вы заботитесь о том, что порядок вещей

+1

Это просто неправильно. Если вы специально не запрашиваете заказы, SQL-сервер не обязан возвращать строки в любом порядке. (конечно, 'ORDER BY' - это способ запросить заказ, это правда) – Piskvor

+0

Yeh Я подумал, что это возможно, спасибо за исправление. –

2

Как сказал Piskvor, MySQL будет заказать запрос, однако, он считает наиболее удобным. Чтобы решить «почему» часть вашего вопроса, разные заказы на результат, вероятно, являются побочным эффектом различных планов выполнения. Если у вас есть индекс на difficulties, второй запрос будет использовать его, но первый не будет.

+0

+1 Хорошая точка, также иллюстрирует, почему плохо делать 'SELECT *' - это может заставить полностью сканировать таблицу (медленно) – Piskvor

1

Без оговорки ORDER BY результаты будут возвращены в случайном порядке. Однако мне кажется логичным, что самый простой (и самый быстрый) способ для db-движка вернуть данные по мере их хранения. Вот почему набор результатов кулака упорядочен PK (без фрагментации, логический порядок не отличается от физического).Во втором случае я бы предположил, что у вас есть индекс в поле name, а для запроса select name from difficulties этот показатель покрывает, поэтому движок db сканирует этот индекс, и именно поэтому вы видите результаты, упорядоченные по name. В любом случае, вы не должны полагаться на такой «заказ по умолчанию».