2010-07-29 90 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 tutorialthe documentation

+0

谢谢Piskvor,这一切都有道理。我知道关于顺序,我只是好奇在这种情况下发生了什么。我想我错误地认为按照记录出现在表中的顺序返回记录(或记录中的字段)对于dbms来说是最简单/最便宜的事情,因此它会做什么,但我有没有什么可以根据这个假设:)欢呼,最大 – 2010-07-29 16:32:06

+0

@Max威廉姆斯:我猜想@ a1ex07是正确的那里与覆盖指数(即在'名称列'的索引)是XE?这会让“只读索引”成为请求“name”列时最便宜的操作,而不是在请求所有列时。见例如这个更长的解释:http://peter-zaitsev.livejournal.com/6949.html – Piskvor 2010-07-29 19:44:22

-2

select name from difficulties应该按照字母顺序返回值,因为它是一个文本字段。 和select * from difficulties将以数字顺序返回,我相信。不要把我抱到笑

做的最好的办法是使用ORDER BY如果你关心什么顺序事情

+1

这只是事实上是错误的。除非您明确要求订购,否则SQL服务器不需要以任何顺序返回行。 (当然,'ORDER BY'是要求订购的方式,很多情况都是如此) – Piskvor 2010-07-29 15:51:33

+0

我认为这可能是,谢谢你的纠正。 – 2010-07-29 16:10:27

2

正如Piskvor说,MySQL将责令查询但其认为最方便的。要解决问题的“为什么”部分,不同的结果顺序可能是不同执行计划的副作用。如果你有一个索引difficulties,第二个查询会使用它,但第一个不会。

+0

+1好点,也说明了为什么不好做'SELECT *' - 它可以强制全表扫描(慢) – Piskvor 2010-07-29 16:16:01

1

没有ORDER BY子句,结果以随机顺序返回。然而,对我来说,数据库引擎在存储数据时最简单(也是最快)的方式似乎是合乎逻辑的。所以这就是为什么第一个结果集按PK排序(没有碎片,逻辑顺序与物理相同)。在第二种情况下,我会假设您有一个name字段的索引,对于查询select name from difficulties这个索引正在覆盖,所以db引擎会扫描这个索引,这就是为什么您看到按name排序的结果。无论如何,你不应该依赖这种“默认”排序。