11---
2- title : Clustered Indexes
3- summary : 了解聚簇索引的概念、用户场景 、用法、限制和兼容性。
2+ title : 聚簇索引
3+ summary : 了解聚簇索引的概念、使用场景 、用法、限制和兼容性。
44---
55
6- # Clustered Indexes
6+ # 聚簇索引
77
8- TiDB 从 v5.0 版本开始支持聚簇索引功能 。该功能控制包含主键的表中数据的存储方式。它赋予 TiDB 以组织表的能力,从而可以提升某些查询的性能 。
8+ 自 v5.0 起,TiDB 支持聚簇索引功能 。该功能控制包含主键的表中数据的存储方式,使 TiDB 能够以提升特定查询性能的方式组织表数据 。
99
10- 在此上下文中, _ clustered_ 一词指的是 _ 数据存储的组织方式 _ ,而不是 _ 一组协同工作的数据库服务器_ 。一些数据库管理系统将聚簇索引表称为 _ index-organized tables _ (IOT)。
10+ 此处的 _ clustered_ 指的是 _ 数据的存储组织方式 _ ,而不是 _ 一组协同工作的数据库服务器_ 。某些数据库管理系统将聚簇索引表称为 _ 索引组织表 _ (IOT)。
1111
12- 目前,TiDB 中包含主键的表被划分为以下两类 :
12+ 目前,TiDB 中包含主键的表分为以下两类 :
1313
14- - ` NONCLUSTERED ` :表的主键是非聚簇索引。在具有非聚簇索引的表中 ,行数据的键由 TiDB 隐式分配的内部 ` _tidb_rowid ` 组成 。由于主键本质上是唯一索引,具有非聚簇索引的表存储一行数据需要至少两个键值对,分别是 :
15- - ` _tidb_rowid ` (键) - 行数据(值)
16- - 主键数据(键) - ` _tidb_rowid ` (值)
17- - ` CLUSTERED ` :表的主键是聚簇索引。在具有聚簇索引的表中,行数据的键由用户提供的主键数据组成 。因此,具有聚簇索引的表只需一个键值对即可存储一行数据 ,即:
18- - 主键数据(键) - 行数据(值)
14+ - ` NONCLUSTERED ` :表的主键为非聚簇索引。在非聚簇索引表中 ,行数据的键由 TiDB 隐式分配的内部 [ ` _tidb_rowid ` ] ( /tidb-rowid.md ) 值组成 。由于主键本质上是唯一索引,非聚簇索引表存储一行数据至少需要两个键值对,分别为 :
15+ - ` _tidb_rowid ` (键)- 行数据(值)
16+ - 主键数据(键)- ` _tidb_rowid ` (值)
17+ - ` CLUSTERED ` :表的主键为聚簇索引。在聚簇索引表中,行数据的键由用户指定的主键数据组成 。因此,聚簇索引表存储一行数据只需一个键值对 ,即:
18+ - 主键数据(键)- 行数据(值)
1919
20- > ** Note: **
20+ > ** 注意: **
2121>
22- > TiDB 仅支持通过表的 ` PRIMARY KEY ` 进行聚簇。启用聚簇索引后,_ the_ ` PRIMARY KEY ` 和 _ the clustered index_ 这两个术语可能会交替使用 。` PRIMARY KEY ` 指的是约束(逻辑属性),而聚簇索引描述的是数据存储的物理实现 。
22+ > TiDB 仅支持按表的 ` PRIMARY KEY ` 进行聚簇。启用聚簇索引后,_ the_ ` PRIMARY KEY ` 和 _ the clustered index_ 这两个术语可能会互换使用 。` PRIMARY KEY ` 指的是约束(逻辑属性),而聚簇索引描述了数据存储的物理实现方式 。
2323
24- ## 用户场景
24+ ## 使用场景
2525
26- 与具有非聚簇索引的表相比,具有聚簇索引的表在以下场景中提供更高的性能和吞吐量优势 :
26+ 与非聚簇索引表相比,聚簇索引表在以下场景下具有更高的性能和吞吐优势 :
2727
28- + 插入数据时,聚簇索引减少了一次网络索引数据的写入 。
29- + 当查询条件相等且只涉及主键时,聚簇索引减少了一次网络索引数据的读取 。
30- + 当范围条件查询只涉及主键时,聚簇索引减少了多次网络索引数据的读取 。
31- + 当查询条件相等或范围条件只涉及主键前缀时,聚簇索引减少了多次网络索引数据的读取 。
28+ + 插入数据时,聚簇索引减少了一次索引数据的网络写入 。
29+ + 当查询等值条件仅涉及主键时,聚簇索引减少了一次索引数据的网络读取 。
30+ + 当查询范围条件仅涉及主键时,聚簇索引减少了多次索引数据的网络读取 。
31+ + 当查询等值或范围条件仅涉及主键前缀时,聚簇索引减少了多次索引数据的网络读取 。
3232
33- 另一方面,具有聚簇索引的表也存在一些缺点。请参见以下内容 :
33+ 另一方面,聚簇索引表也存在一些劣势,如下所示 :
3434
3535- 当插入大量值接近的主键时,可能会出现写入热点问题。
36- - 如果主键的数据类型大于 64 位,尤其是在存在多个二级索引的情况下 ,表数据会占用更多存储空间。
36+ - 如果主键的数据类型大于 64 位,尤其存在多个二级索引时 ,表数据会占用更多存储空间。
3737
3838## 用法
3939
40- ### 创建带有聚簇索引的表
40+ ### 创建带聚簇索引的表
4141
4242自 TiDB v5.0 起,你可以在 ` CREATE TABLE ` 语句中,在 ` PRIMARY KEY ` 后添加非保留关键字 ` CLUSTERED ` 或 ` NONCLUSTERED ` ,以指定表的主键是否为聚簇索引。例如:
4343
@@ -50,9 +50,9 @@ CREATE TABLE t (a BIGINT, b VARCHAR(255), PRIMARY KEY(a, b) CLUSTERED);
5050CREATE TABLE t (a BIGINT , b VARCHAR (255 ), PRIMARY KEY (a, b) NONCLUSTERED);
5151```
5252
53- 注意,` KEY ` 和 ` PRIMARY KEY ` 在列定义中具有相同的含义 。
53+ 注意,在列定义中,关键字 ` KEY ` 和 ` PRIMARY KEY ` 含义相同 。
5454
55- 你也可以在 TiDB 中使用 [ comment 语法 ] ( /comment-syntax.md ) 来指定主键的类型 。例如:
55+ 你也可以使用 TiDB 的 [ 注释语法 ] ( /comment-syntax.md ) 指定主键类型 。例如:
5656
5757``` sql
5858CREATE TABLE t (a BIGINT PRIMARY KEY /* T![clustered_index] CLUSTERED */ , b VARCHAR (255 ));
@@ -61,44 +61,44 @@ CREATE TABLE t (a BIGINT, b VARCHAR(255), PRIMARY KEY(a, b) /*T![clustered_index
6161CREATE TABLE t (a BIGINT , b VARCHAR (255 ), PRIMARY KEY (a, b) /* T![clustered_index] NONCLUSTERED */ );
6262```
6363
64- 对于未显式指定 ` CLUSTERED ` /` NONCLUSTERED ` 关键字的语句,默认行为由系统变量 [ ` @@global.tidb_enable_clustered_index ` ] ( /system-variables.md#tidb_enable_clustered_index-new-in-v50 ) 控制。支持的取值如下 :
64+ 对于未显式指定 ` CLUSTERED ` /` NONCLUSTERED ` 关键字的语句,默认行为由系统变量 [ ` @@global.tidb_enable_clustered_index ` ] ( /system-variables.md#tidb_enable_clustered_index-new-in-v50 ) 控制。该变量支持的取值如下 :
6565
66- - ` OFF ` 表示默认创建主键为非聚簇索引 。
67- - ` ON ` 表示默认创建主键为聚簇索引 。
68- - ` INT_ONLY ` 表示行为由配置项 ` alter-primary-key ` 控制。如果 ` alter-primary-key ` 设置为 ` true ` ,则默认创建非聚簇索引的主键 ;如果设置为 ` false ` ,则只有由整数列组成的主键会被创建为聚簇索引 。
66+ - ` OFF ` 表示主键默认创建为非聚簇索引 。
67+ - ` ON ` 表示主键默认创建为聚簇索引 。
68+ - ` INT_ONLY ` 表示行为由配置项 ` alter-primary-key ` 控制。如果 ` alter-primary-key ` 设置为 ` true ` ,主键默认创建为非聚簇索引 ;如果设置为 ` false ` ,仅由整数型列组成的主键默认创建为聚簇索引 。
6969
70- 系统变量 ` @@global.tidb_enable_clustered_index ` 的默认值为 ` ON ` 。
70+ ` @@global.tidb_enable_clustered_index ` 的默认值为 ` ON ` 。
7171
7272### 添加或删除聚簇索引
7373
74- TiDB 不支持在表创建后添加或删除聚簇索引,也不支持聚簇索引与非聚簇索引之间的相互转换 。例如:
74+ TiDB 不支持在表创建后添加或删除聚簇索引,也不支持聚簇索引与非聚簇索引之间的互相转换 。例如:
7575
7676``` sql
77- ALTER TABLE t ADD PRIMARY KEY (b, a) CLUSTERED; -- 目前不支持 。
78- ALTER TABLE t DROP PRIMARY KEY ; -- 如果主键是聚簇索引 ,则不支持。
79- ALTER TABLE t DROP INDEX ` PRIMARY` ; -- 如果主键是聚簇索引 ,则不支持。
77+ ALTER TABLE t ADD PRIMARY KEY (b, a) CLUSTERED; -- 当前不支持 。
78+ ALTER TABLE t DROP PRIMARY KEY ; -- 如果主键为聚簇索引 ,则不支持。
79+ ALTER TABLE t DROP INDEX ` PRIMARY` ; -- 如果主键为聚簇索引 ,则不支持。
8080```
8181
8282### 添加或删除非聚簇索引
8383
84- TiDB 支持在表创建后添加或删除非聚簇索引。可以显式指定关键字 ` NONCLUSTERED ` ,也可以省略。例如:
84+ TiDB 支持在表创建后添加或删除非聚簇索引。你可以显式指定 ` NONCLUSTERED ` 关键字 ,也可以省略。例如:
8585
8686``` sql
8787ALTER TABLE t ADD PRIMARY KEY (b, a) NONCLUSTERED;
88- ALTER TABLE t ADD PRIMARY KEY (b, a); -- 省略关键字时 ,主键默认为非聚簇索引。
88+ ALTER TABLE t ADD PRIMARY KEY (b, a); -- 如果省略关键字 ,主键默认为非聚簇索引。
8989ALTER TABLE t DROP PRIMARY KEY ;
9090ALTER TABLE t DROP INDEX ` PRIMARY` ;
9191```
9292
93- ### 查询主键是否为聚簇索引
93+ ### 检查主键是否为聚簇索引
9494
9595你可以通过以下方法之一检查表的主键是否为聚簇索引:
9696
9797- 执行命令 ` SHOW CREATE TABLE ` 。
9898- 执行命令 ` SHOW INDEX FROM ` 。
9999- 查询系统表 ` information_schema.tables ` 中的 ` TIDB_PK_TYPE ` 列。
100100
101- 通过运行 ` SHOW CREATE TABLE ` ,可以看到 ` PRIMARY KEY ` 的属性是 ` CLUSTERED ` 还是 ` NONCLUSTERED ` 。例如:
101+ 通过执行 ` SHOW CREATE TABLE ` 命令 ,可以看到 ` PRIMARY KEY ` 的属性是 ` CLUSTERED ` 还是 ` NONCLUSTERED ` 。例如:
102102
103103``` sql
104104mysql> SHOW CREATE TABLE t;
@@ -114,7 +114,7 @@ mysql> SHOW CREATE TABLE t;
1141141 row in set (0 .01 sec)
115115```
116116
117- 通过运行 ` SHOW INDEX FROM ` ,可以检查 ` Clustered ` 列的结果是否显示为 ` YES ` 或 ` NO ` 。例如:
117+ 通过执行 ` SHOW INDEX FROM ` 命令 ,可以检查 ` Clustered ` 列的结果是否为 ` YES ` 或 ` NO ` 。例如:
118118
119119``` sql
120120mysql> SHOW INDEX FROM t;
@@ -126,7 +126,7 @@ mysql> SHOW INDEX FROM t;
1261261 row in set (0 .01 sec)
127127```
128128
129- 你也可以查询系统表 ` information_schema.tables ` 中的 ` TIDB_PK_TYPE ` 列,判断结果是否为 ` CLUSTERED ` 或 ` NONCLUSTERED ` 。例如:
129+ 你还可以查询系统表 ` information_schema.tables ` 中的 ` TIDB_PK_TYPE ` 列,查看结果是 ` CLUSTERED ` 还是 ` NONCLUSTERED ` 。例如:
130130
131131``` sql
132132mysql> SELECT TIDB_PK_TYPE FROM information_schema .tables WHERE table_schema = ' test' AND table_name = ' t' ;
@@ -140,15 +140,15 @@ mysql> SELECT TIDB_PK_TYPE FROM information_schema.tables WHERE table_schema = '
140140
141141## 限制
142142
143- 目前,聚簇索引功能存在若干限制。请参见以下内容 :
143+ 目前,聚簇索引功能存在多种类型的限制,具体如下 :
144144
145- - 不支持且不在支持计划中的场景 :
146- - 不支持将聚簇索引与属性 [ ` SHARD_ROW_ID_BITS ` ] ( /shard-row-id-bits.md ) 一起使用 。同时,属性 [ ` PRE_SPLIT_REGIONS ` ] ( /sql-statements/sql-statement-split-region.md#pre_split_regions ) 不对非 [ ` AUTO_RANDOM ` ] ( /auto-random.md ) 的聚簇索引表生效 。
147- - 不支持对具有聚簇索引的表进行降级 。如果需要降级此类表,请使用逻辑备份工具迁移数据 。
148- - 尚未支持但在支持计划中的场景 :
149- - 不支持使用 ` ALTER TABLE ` 语句添加、删除或修改聚簇索引 。
145+ - 不支持且暂无支持计划的场景 :
146+ - 聚簇索引与属性 [ ` SHARD_ROW_ID_BITS ` ] ( /shard-row-id-bits.md ) 不支持同时使用 。同时,属性 [ ` PRE_SPLIT_REGIONS ` ] ( /sql-statements/sql-statement-split-region.md#pre_split_regions ) 对于非 [ ` AUTO_RANDOM ` ] ( /auto-random.md ) 的聚簇索引表无效 。
147+ - 不支持对聚簇索引表进行降级 。如果需要降级此类表,请使用逻辑备份工具进行数据迁移 。
148+ - 尚未支持但有支持计划的场景 :
149+ - 通过 ` ALTER TABLE ` 语句添加、删除或修改聚簇索引暂不支持 。
150150
151- 如果你将聚簇索引与属性 ` SHARD_ROW_ID_BITS ` 一起使用 ,TiDB 会报错 :
151+ 如果你将聚簇索引与属性 ` SHARD_ROW_ID_BITS ` 同时使用 ,TiDB 会报如下错误 :
152152
153153``` sql
154154mysql> CREATE TABLE t (a VARCHAR (255 ) PRIMARY KEY CLUSTERED) SHARD_ROW_ID_BITS = 3 ;
@@ -157,34 +157,34 @@ ERROR 8200 (HY000): Unsupported shard_row_id_bits for table with primary key as
157157
158158## 兼容性
159159
160- ### 与早期及后续版本的 TiDB 兼容性
160+ ### 与早期和后续 TiDB 版本的兼容性
161161
162- TiDB 支持升级带有聚簇索引的表,但不支持降级此类表,也就是说,后续版本中带有聚簇索引的表中的数据在早期版本中不可用 。
162+ TiDB 支持对聚簇索引表进行升级,但不支持降级。这意味着在较高版本 TiDB 上的聚簇索引表数据无法在较低版本上使用 。
163163
164- 聚簇索引功能在 TiDB v3.0 和 v4.0 中部分支持。满足以下全部条件时 ,默认启用:
164+ 聚簇索引功能在 TiDB v3.0 和 v4.0 中为部分支持。仅当以下条件全部满足时 ,默认启用:
165165
166166- 表包含 ` PRIMARY KEY ` 。
167- - ` PRIMARY KEY ` 仅由一列组成 。
168- - ` PRIMARY KEY ` 为 ` INTEGER ` 。
167+ - ` PRIMARY KEY ` 仅包含一列 。
168+ - ` PRIMARY KEY ` 为整数型 。
169169
170- 自 TiDB v5.0 起,聚簇索引功能对所有类型的主键都已完全支持 ,但默认行为与 TiDB v3.0 和 v4.0 保持一致。若要更改默认行为,可以将系统变量 ` @@tidb_enable_clustered_index ` 设置为 ` ON ` 或 ` OFF ` 。更多详情请参见 [ Create a table with clustered indexes ] ( #create-a-table-with-clustered-indexes ) 。
170+ 自 TiDB v5.0 起,聚簇索引功能对所有类型的主键均完全支持 ,但默认行为与 TiDB v3.0 和 v4.0 保持一致。你可以通过配置系统变量 ` @@tidb_enable_clustered_index ` 为 ` ON ` 或 ` OFF ` 来更改默认行为。详情参见 [ 创建带聚簇索引的表 ] ( #创建带聚簇索引的表 ) 。
171171
172172### 与 MySQL 的兼容性
173173
174- TiDB 特定的注释语法支持将关键字 ` CLUSTERED ` 和 ` NONCLUSTERED ` 包裹在注释中 。` SHOW CREATE TABLE ` 的结果也包含 TiDB 特定的 SQL 注释。早期版本的 MySQL 和 TiDB 数据库会忽略这些注释。
174+ TiDB 特有的注释语法支持将 ` CLUSTERED ` 和 ` NONCLUSTERED ` 关键字包裹在注释中 。` SHOW CREATE TABLE ` 的结果也包含 TiDB 特有的 SQL 注释。MySQL 数据库和早期版本的 TiDB 数据库会忽略这些注释。
175175
176176### 与 TiDB 迁移工具的兼容性
177177
178- 聚簇索引功能仅与 v5.0 及更高版本中的以下迁移工具兼容 :
178+ 聚簇索引功能仅在 v5.0 及以上版本与以下迁移工具兼容 :
179179
180- - 备份与还原工具 :BR、Dumpling 和 TiDB Lightning。
181- - 数据迁移与复制工具 :DM 和 TiCDC。
180+ - 备份与恢复工具 :BR、Dumpling 和 TiDB Lightning。
181+ - 数据迁移与同步工具 :DM 和 TiCDC。
182182
183- 但你不能通过使用 v5.0 版本的 BR 工具备份和还原表,来实现非聚簇索引表向聚簇索引表的转换 ,反之亦然。
183+ 但是,你无法通过 v5.0 版本的 BR 工具备份并恢复表来实现非聚簇索引表与聚簇索引表之间的互相转换 ,反之亦然。
184184
185185### 与其他 TiDB 功能的兼容性
186186
187- 对于具有组合主键或单一非整数主键的表 ,如果你将主键从非聚簇索引更改为聚簇索引,其行数据的索引也会发生变化 。因此,在 TiDB v5.0 之前版本中可执行的 ` SPLIT TABLE BY/BETWEEN ` 语句在 v5.0 及之后的版本中不再适用。如果你想使用 ` SPLIT TABLE BY/BETWEEN ` 来拆分带有聚簇索引的表,需要提供主键列的值 ,而不是指定整数值。示例如下:
187+ 对于联合主键或单一非整数型主键的表 ,如果你将主键从非聚簇索引更改为聚簇索引,其行数据的键也会发生变化 。因此,在 TiDB v5.0 之前可执行的 ` SPLIT TABLE BY/BETWEEN ` 语句,在 v5.0 及以上版本的 TiDB 中将不再适用。如果你希望对带聚簇索引的表使用 ` SPLIT TABLE BY/BETWEEN ` ,则需要提供主键列的值 ,而不是指定整数值。示例如下:
188188
189189``` sql
190190mysql> create table t (a int , b varchar (255 ), primary key (a, b) clustered);
@@ -209,7 +209,7 @@ mysql> split table t by (0, ''), (50000, ''), (100000, '');
2092091 row in set (0.01 sec)
210210```
211211
212- 属性 [`AUTO_RANDOM`](/auto-random.md) 只能用于聚簇索引,否则 TiDB 会返回以下错误 :
212+ 属性 [`AUTO_RANDOM`](/auto-random.md) 只能用于聚簇索引,否则 TiDB 会返回如下错误 :
213213
214214```sql
215215mysql> create table t (a bigint primary key nonclustered auto_random);
0 commit comments