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

问题描述 投票:0回答:2

我有一张桌子

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 行。所以我有点困惑,不知道该怎么办。

mysql sorting sql-order-by
2个回答
6
投票

如果我们希望以特定顺序返回行,我们可以在查询中指定合适的

ORDER BY
子句。

表中的行需要“排序”的想法与关系数据库理论背道而驰。 (关系是一组元组;改变关系中元组的“顺序”不会改变关系。)

将理论转化为实践,对于 InnoDB 存储引擎,将

ORDER BY
指定为表属性是没有意义的,因为 InnoDB 表始终是有序的(按顺序存储的行),按其簇索引排列。

对于 MyISAM 存储引擎,指定

ORDER BY
可能会提高某些查询的性能。
ALTER TABLE ... ORDER BY
语句仅重组表一次。运行后续
DELETE
INSERT
UPDATE
语句时,可能不会保留行的“顺序”。

重申:如果我们需要以特定顺序返回行,我们不应该依赖于行物理存储在表中的“顺序”。我们必须在查询中包含

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`)
)

实际上,我们永远不会这样做......因为任何二级索引都将包含主键值作为返回集群索引的“指针”,这将是一种令人难以置信的资源浪费。在实践中,我们将

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 (`id`)
, KEY `tableMain_IX1` (`value2`,`value3`,`value4`)
)

0
投票

在我看来,innodb 会忽略数据的默认(你的)顺序,而 myisam 则不会。

© www.soinside.com 2019 - 2024. All rights reserved.