【问题标题】:MySQL default order depends on WHERE [duplicate]MySQL默认顺序取决于WHERE [重复]
【发布时间】:2011-12-13 11:40:27
【问题描述】:

可能重复:
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'

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

谁能告诉我这是怎么发生的?

【问题讨论】:

  • country 已编入索引,可能country 索引与sort_order 的顺序不同,或者根本没有排序。或者在你的情况下,它是意外倒序的......
  • ORDER BY 对于包含用户定义的聚集索引(PRIMARY KEY 或 NOT NULL UNIQUE 索引)的 InnoDB 表没有意义。如果存在这样的索引,InnoDB 总是根据这样的索引对表行进行排序。 - dev.mysql.com/doc/refman/5.1/en/alter-table.html - 我知道你的表引擎是 MEMORY,但我认为情况是一样的。
  • 这似乎类似于:stackoverflow.com/questions/725717/….. 文档除外:请注意,插入和删除后表不会保持此顺序。此选项主要在您知道大部分时间以特定顺序查询行时很有用。通过在对表进行重大更改后使用此选项,您可能可以获得更高的性能。在某些情况下,如果表按您以后要排序的列排序,则可能会使 MySQL 更容易排序...可能,可能...不要依赖

标签: mysql


【解决方案1】:

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

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

“ORDER BY 使您可以创建具有特定顺序的行的新表。请注意,插入和删除后该表不会保持此顺序。此选项主要在您知道您主要查询时很有用大多数情况下,行是按特定顺序排列的。通过在对表进行重大更改后使用此选项,您可能可以获得更高的性能。在某些情况下,如果表按顺序排列,可能会使 MySQL 更容易排序您想稍后对其进行排序的列。"

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

【讨论】:

  • +1 如果还不够清楚:SQL 语言中不存在 默认顺序 的概念。这是有意设计的。
  • IMO 更好的答案,因为它会在文档中引用它们并直接指示为所有查询添加 order by。
  • 这并没有回答为什么会发生的问题。我不想知道这是否是首选方式,但我需要知道引擎为什么决定反转排序顺序。此外,文档没有说明我应该在查询中使用 ORDER BY
【解决方案2】:

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

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

【讨论】:

  • Just add the ORDER BY statement to all your queries. 这是正确答案。 SQL 从不 保证结果集的任何特定顺序,除非您使用ORDER BY 子句。行在表中的物理存储顺序无关紧要。
  • 而 MySQL 没有DESC 索引。
【解决方案3】:

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

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;

【讨论】:

  • 因为这不是问题所在。问题是为什么 MYSQL 在表上具有允许默认顺序(如果它不起作用)的功能。 (或者为什么它在他们的实施中不起作用
  • 我知道 order by 应该对结果集起作用。我第一次听说您可以在更改声明中进行订购。如果我得到解决方案,我会尝试阅读它,而不是让你知道..
【解决方案4】:

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

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

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

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

【讨论】:

  • 如果是这种情况,它应该以随机顺序显示 sort_order,但它以 DESC 顺序完美显示。
  • 只是因为它不是你想要的顺序并不意味着它是随机顺序。以 MySQL 认为最方便的顺序向您展示它们。当表格按 DESC 顺序排列时,恰好该顺序与您想要的顺序一致。
猜你喜欢
  • 2012-01-29
  • 2020-08-11
  • 2017-03-02
  • 2017-02-08
  • 2012-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-27
相关资源
最近更新 更多