为什么在MariaDB中添加另一个非聚簇索引时主键不是聚簇索引
Why the primary key is not the clustered index if another non clustered index is added in MariaDB
您好,我有一个 table 通过以下查询创建的 MariaDB 版本 10.5.9
CREATE TABLE `test` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`status` varchar(60) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `test_status_IDX` (`status`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4
我一直认为默认情况下主键是聚集索引,它还定义了 table 中行的顺序,但这里似乎选择了状态索引作为聚集索引。为什么会发生这种情况,我该如何改变它?
MariaDB [test]> select * from test;
+----+--------+
| id | status |
+----+--------+
| 2 | cfrc |
| 5 | hjr |
| 1 | or |
| 3 | test |
| 6 | verve |
| 4 | yes |
+----+--------+
6 rows in set (0.001 sec)
假设 SELECT 的结果将按 dB 引擎中的任何列排序是不安全的。如果您希望进行排序,则应始终使用 ORDER BY col [ASC|DESC]。我看到记录按添加顺序显示,但在 deletions/insertions 等之后可能会发生变化,因此不应依赖。有关详细信息,请参阅 here。
@aprsa 是对的我错误地假设结果将与聚集索引的顺序相同但在这种情况下(使用 INNODB)状态索引用于查询的评估所以这就是为什么它看起来是 'sorted' 按状态。如果我 select id 则使用主索引并且结果似乎是 'sorted' by id。在另一个引擎中,这可能不是真的。
那个特定的 table 由 2 个 BTree 组成:
数据,按PRIMARY KEY
排序。是的,它是聚类的,顺序为 1,2,3,...
二级索引,按status
排序。每个二级索引都包含一个 PK 的副本,这样它就可以进入另一个 BTree 以获取其余的列(不是说还有更多!)。也就是说,BTree 相当于一个 2 列 table 和 PRIMARY KEY(status)
加上一个 id
.
注意输出的顺序是 status
。我必须假设它决定简单地按顺序读取二级索引来提供结果。
是的,如果您想要特定的顺序,您必须指定一个ORDER BY
。您绝不能假设我刚才讨论的细节。谁知道,明天可能会有其他事情发生,例如 in-memory 以其他方式对信息进行加扰的“散列”!
(此答案适用于 MySQL 和 MariaDB。但是,MariaDB 已经在玩 MySQL 尚未采用的散列游戏。警告!或简单地添加一个 ORDER BY
.)
您好,我有一个 table 通过以下查询创建的 MariaDB 版本 10.5.9
CREATE TABLE `test` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`status` varchar(60) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `test_status_IDX` (`status`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4
我一直认为默认情况下主键是聚集索引,它还定义了 table 中行的顺序,但这里似乎选择了状态索引作为聚集索引。为什么会发生这种情况,我该如何改变它?
MariaDB [test]> select * from test;
+----+--------+
| id | status |
+----+--------+
| 2 | cfrc |
| 5 | hjr |
| 1 | or |
| 3 | test |
| 6 | verve |
| 4 | yes |
+----+--------+
6 rows in set (0.001 sec)
假设 SELECT 的结果将按 dB 引擎中的任何列排序是不安全的。如果您希望进行排序,则应始终使用 ORDER BY col [ASC|DESC]。我看到记录按添加顺序显示,但在 deletions/insertions 等之后可能会发生变化,因此不应依赖。有关详细信息,请参阅 here。
@aprsa 是对的我错误地假设结果将与聚集索引的顺序相同但在这种情况下(使用 INNODB)状态索引用于查询的评估所以这就是为什么它看起来是 'sorted' 按状态。如果我 select id 则使用主索引并且结果似乎是 'sorted' by id。在另一个引擎中,这可能不是真的。
那个特定的 table 由 2 个 BTree 组成:
数据,按
PRIMARY KEY
排序。是的,它是聚类的,顺序为 1,2,3,...二级索引,按
status
排序。每个二级索引都包含一个 PK 的副本,这样它就可以进入另一个 BTree 以获取其余的列(不是说还有更多!)。也就是说,BTree 相当于一个 2 列 table 和PRIMARY KEY(status)
加上一个id
.
注意输出的顺序是 status
。我必须假设它决定简单地按顺序读取二级索引来提供结果。
是的,如果您想要特定的顺序,您必须指定一个ORDER BY
。您绝不能假设我刚才讨论的细节。谁知道,明天可能会有其他事情发生,例如 in-memory 以其他方式对信息进行加扰的“散列”!
(此答案适用于 MySQL 和 MariaDB。但是,MariaDB 已经在玩 MySQL 尚未采用的散列游戏。警告!或简单地添加一个 ORDER BY
.)