MySQL默认顺序取决于WHERE

时间:2011-12-13 11:40:28

标签: mysql

  

可能重复:
  Default sort-ordering in MySQL (ALTER TABLE … ORDER BY …;)

我有一张这样的表:

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'

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

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

4 个答案:

答案 0 :(得分:5)

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

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

“ORDER BY允许您按特定顺序创建包含行的新表。请注意,在插入和删除后,表格不会按此顺序保留。此选项主要在您知道自己主要要查询时有用大多数时候以特定顺序排列。通过在对表进行重大更改后使用此选项,您可能可以获得更高的性能。在某些情况下,如果表按顺序排列,则可能使MySQL更容易排序。您希望稍后订购的列。“

所以你必须在查询中使用ORDER BY表达式。

答案 1 :(得分:3)

我猜你的国家/地区索引的默认顺序是DESC。因此,如果使用这个,你会得到“错误的”订单,而在所有其他情况下,它会有所不同。不确定是否或如何在mysql中指定索引的顺序,但我认为是。

但是如果你没有指定一个,我仍然不确定你是否可以依赖订单。只需将ORDER BY语句添加到您的所有查询中即可。

答案 2 :(得分: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;

答案 3 :(得分:1)

您看到此行为的原因可能如下:因为WHERE子句按country过滤,MySQL使用country上的索引来查找要返回的行。很可能索引行按country排序,然后按id(表的主键)排序。这意味着MySQL检索行的最有效方法是读取索引引用的行,按它们在索引中出现的顺序。因此,行在磁盘上显示的顺序无关紧要。

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

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

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