2011-12-13 52 views
6

可能重复:
Default sort-ordering in MySQL (ALTER TABLE … ORDER BY …;)MySQL的默认顺序取决于WHERE

我有这样的一个表:

CREATE TABLE IF NOT EXISTS `table_test` (
    `id` mediumint(8) unsigned NOT NULL, 
    `country` enum('AF','AX','AL') DEFAULT NULL, 
    `number` tinyint(3) unsigned DEFAULT NULL, 
    `sort_order` double unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`id`), 
    KEY `country` (`country`), 
    KEY `id` (`id`,`country`) 
) ENGINE=MEMORY DEFAULT CHARSET=latin1; 

我有我换了一台默认排序如:

ALTER TABLE test_table ORDER BY sort_order ASC; 

该表从不更新,并且在其生命周期中不删除或添加任何记录。这一切似乎工作,所以如果我使用以下查询:

SELECT * FROM test_table LIMIT 10 

它以正确的顺序返回10条记录。

即使我用:

SELECT * FROM test_table WHERE num=3 

返回正确的顺序的结果。

但如果我这样做

SELECT * FROM test_table WHERE country='AX' 

它将返回以相反的顺序结果。

有人能告诉我这是怎么发生的吗?

+0

'country'被编入索引,可能'country'索引与sort_order不同,或者它根本没有排序。或者在你的情况下,它意外地反向排序... – Vili

+0

_ORDER BY对于包含用户定义的聚簇索引(PRIMARY KEY或NOT NULL UNIQUE索引)的InnoDB表没有意义。 InnoDB总是按照这样的索引排序表行,如果有的话。 - - http://dev.mysql.com/doc/refman/5.1/en/alter-table.html - 我知道你的表引擎是MEMORY,但是我认为案件是一样的。 – Vili

+0

这似乎是类似于:http://stackoverflow.com/questions/725717/default-sort-ordering-in-mysql-alter-table-order-by ..除了从文档:请注意,该表不保留按照此顺序插入和删除。这个选项主要用于当你知道你主要是在大部分时间以特定顺序查询行时。在对表格进行重大更改后使用此选项,您可能会获得更高的性能。在某些情况下,如果表格按照您希望稍后订购的列顺序排列,可能会使MySQL的排序更容易...可能,May ...不要依赖 – xQbert

回答

5

在表上指定ORDER BY只是帮助引擎加快查询的顺序。它不会强制mysql总是以相同的顺序返回结果。

在此描述:。http://dev.mysql.com/doc/refman/5.1/en/alter-table.html

“ORDER BY,可以创建新表,在一个特定的顺序排注意,表不留在这个顺序插入和删除后,此选项很有用主要是当你知道你主要是按照特定的顺序查询行时,通过在对表进行重大更改后使用这个选项,你可能会获得更高的性能,在某些情况下,它可能会使排序更容易对于MySQL而言,如果表格按照您希望稍后订购的列的顺序排列“

因此,您也必须在查询中使用ORDER BY表达式。

+0

+1如果它不够清楚:*默认顺序的概念*在SQL语言中不存在这是故意的和设计的 –

+0

IMO更好的答案,因为它站点的文档的引用他们,并表明直接向所有查询添加秩序 – xQbert

+0

这并不回答任务离子为什么会发生。我不想知道它是否是首选的方式,但我需要知道引擎为什么决定颠倒排序顺序。此外,文档没有声明我应该在查询 – Nin

1

为什么不尝试查询这样的:

SELECT * FROM test_table ORDER BY sort_order ASC LIMIT 10; 
SELECT * FROM test_table WHERE num=3 ORDER BY sort_order ASC; 
SELECT * FROM test_table WHERE country='AX' ORDER BY sort_order ASC; 
+1

,因为这不是问题。问题是为什么MYSQL在允许缺省订单的表上有一个功能,如果它不起作用的话。 (或者为什么它不是在执行 – xQbert

+0

以及我知道按顺序应该在结果集上工作。我第一次听到你可以在alter语句中进行排序。如果我得到解决方案,我正在尝试阅读它我只会让你知道.. –

3

我猜你的索引的默认顺序上国家是DESC。正因为如此,如果使用这一个,你会得到“错误”的顺序,在所有其他情况下,它是不同的。不知道是否可以在mysql中指定索引的顺序,但我认为是。

但仍然不知道如果你可以依赖的顺序,如果你不指定一个。只需将ORDER BY语句添加到所有查询中。

+0

'只需将ORDER BY语句添加到所有查询中.'这是正确的答案。SQL ** never **保证结果集的任何特定顺序,除非您使用'ORDER BY'子句,这些行在物理上存储在表中的顺序并不重要 – Hammerite

+0

并且MySQL不**具有'DESC'索引 –

1

您看到此行为的原因大概如下:由于WHERE子句按country进行过滤,因此MySQL使用country上的索引来查找要返回的行。索引行很可能按照country排序,然后是id(表的主键)。这意味着MySQL检索行的最有效方式是通过读取索引引用的行,索引中出现的顺序。因此,这些行在磁盘上出现的顺序是不相关的。

的MySQL确实提供了语法允许您指定索引的顺序,但this is currently ignored

的index_col_name规约可以以ASC或DESC结束。这些关键字可用于将来的扩展,用于指定升序或降序索引值存储。目前,他们被解析但被忽略;索引值始终以升序存储。

您必须将ORDER BY子句添加到您的查询中,以确保行按所需顺序返回。顺便说一句,无论如何,情况总是如此。 SQL不保证以任何特定顺序返回行,无论这些行是如何物理存储的(除非存在ORDER BY子句)。

+0

中使用ORDER BY。如果是这种情况,它应该以随机顺序显示sort_order,但它会以DESC顺序完美显示它。 – Nin

+1

仅仅因为它的顺序并不是你想要的,并不意味着它是*随机*顺序。 MySQL以最方便的方式向您展示它。当表格按照DESC顺序排列时,恰好发生该顺序与您想要的顺序一致。 – Hammerite