ORDER BY被忽略,因为表中有一个用户定义的聚簇索引

时间:2015-04-21 19:08:37

标签: mysql sorting sql-order-by

我有一张桌子

CREATE TABLE `tableMain` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `value1` varchar(45) NOT NULL,
   'value2' varchar(50) NOT NULL,
   'value3' int NOT NULL,
   'value4' timestamp NOT NULL,
   'value5' int NOT NULL
PRIMARY KEY (`id`)
)

所以我创建了那个表,我希望它总是按value2排序,如果有两个类似它应该按value3排序并且在value4之后。

所以我试着按照

来做
ALTER TABLE tableMain
ORDER BY value2 ASC, value3 ASC, value4 ASC

当我运行该代码时,我收到一个错误:

  

错误代码:1105。ORDER BY被忽略,因为表'tableMain'中有一个用户定义的聚簇索引

我想补充一点,我把它作为学校的家庭作业,其他有相同任务的人可以运行这个ALTER TABLE行。所以我有点困惑,不知道该怎么做。

1 个答案:

答案 0 :(得分:4)

如果您想要特定序列中的行,请在查询中指定适当的ORDER BY子句。

在表中需要“排序”行的想法在关系数据库理论面前浮现。

关系是一组元组;改变关系中元组的“顺序”并不会改变关系。

将理论转化为实践,使用InnoDB存储引擎,将ORDER BY指定为表属性是没有意义的,因为InnoDB表将始终按其集群索引排序。

对于MyISAM存储引擎,指定ORDER BY可能会提高某些查询的性能。 ALTER TABLE ... ORDER BY语句仅重新组织表一次。运行后续DELETEINSERTUPDATE语句时,可能无法保留行的“顺序”。

重申:如果您需要按特定顺序返回的行,则不能依赖于行物理存储在表中的“顺序”。您必须在查询中包含ORDER BY

要真正提高大型表的性能,可以添加适当的索引。


至于你的同学为什么要运行语句,并且你的语句返回错误...最可能的解释是他们的表使用 MyISAM 存储引擎,而你的表正在使用 InnoDB 存储引擎。

(无论您的任务是什么,更改表的存储引擎都不是正确的答案...... MyISAM存储引擎是某些用例的合适选择;但InnoDB是传统“关系数据库”的最合适选择用例。)


如果您的要求是您的InnoDB表“总是按一组列排序”(无论出于何种原因),那么让集群索引包含这些列作为前导列。您可以通过将这些列声明为表的PRIMARY KEY的前导列来实现。您可以在id列上创建一个独特的索引。

CREATE TABLE `tableMain` 
( `id` INT(11) NOT NULL AUTO_INCREMENT
, `value1` VARCHAR(45) NOT NULL
, `value2` VARCHAR(50) NOT NULL
, `value3` INT NOT NULL
, `value4` TIMESTAMP NOT NULL
, `value5` INT NOT NULL
, PRIMARY KEY (`value2`,`value3`,`value4`,`id`)
, UNIQUE KEY `tableMain_UX1` (`id`)
)

实际上,我们永远不会这样做...因为任何二级索引都会将PRIMARY KEY值作为“指针”包含在群集索引中,这将是一种令人难以置信的资源浪费。在实践中,我们将id作为表的PRIMARY KEY,并在其他列上创建二级索引......

CREATE TABLE `tableMain` 
( `id` INT(11) NOT NULL AUTO_INCREMENT
, `value1` VARCHAR(45) NOT NULL
, `value2` VARCHAR(50) NOT NULL
, `value3` INT NOT NULL
, `value4` TIMESTAMP NOT NULL
, `value5` INT NOT NULL
, PRIMARY KEY (`id`)
, KEY `tableMain_IX1` (`value2`,`value3`,`value4`)
)