@@ -1175,7 +1175,7 @@ ALTER TABLE member_level PARTITION BY RANGE(level)
11751175 PARTITION pMax VALUES LESS THAN (MAXVALUE));
11761176```
11771177
1178- 对普通表进行分区或者对分区表进行重新分区时,可以根据需要将索引更新为全局索引或普通索引 :
1178+ 对普通表进行分区或者对分区表进行重新分区时,可以根据需要将索引更新为 [ 全局索引 ] ( /global-indexes.md ) 或普通索引 :
11791179
11801180``` sql
11811181CREATE TABLE t1 (
@@ -1473,7 +1473,7 @@ SELECT store_id, COUNT(department_id) AS c
14731473
14741474> ** 注意:**
14751475>
1476- > 使用[ 全局索引] ( #全局索引 ) 时,可以忽略该规则。
1476+ > 使用[ 全局索引] ( /global-indexes.md ) 时,可以忽略该规则。
14771477
14781478这里所指的唯一也包含了主键,因为根据主键的定义,主键必须是唯一的。例如,下面这些建表语句就是无效的:
14791479
@@ -1686,103 +1686,7 @@ ERROR 8264 (HY000): Global Index is needed for index 'a', since the unique index
16861686
16871687### 全局索引
16881688
1689- 在引入全局索引 (Global Index) 之前,TiDB 会为每个分区创建一个局部索引 (Local Index),即一个分区对应一个局部索引。这种索引方式存在一个[ 使用限制] ( #分区键主键和唯一键 ) :主键和唯一键必须包含所有的分区键,以确保数据的全局唯一性。此外,当查询的数据跨越多个分区时,TiDB 需要扫描各个分区的数据才能返回结果。
1690-
1691- 为解决这些问题,TiDB 从 v8.3.0 开始引入全局索引。全局索引能覆盖整个表的数据,使得主键和唯一键在不包含分区键的情况下仍能保持全局唯一性。此外,全局索引可以在一次操作中访问多个分区的索引数据,而无需对每个分区的局部索引逐一查找,显著提升了针对非分区键的查询性能。从 v8.5.4 开始,非唯一索引也可以创建为全局索引。
1692-
1693- 如果你需要创建全局索引,可以通过在索引定义中添加 ` GLOBAL ` 关键字来实现。
1694-
1695- > ** 注意:**
1696- >
1697- > 全局索引对分区管理有影响,执行 ` DROP ` 、` TRUNCATE ` 和 ` REORGANIZE PARTITION ` 操作也会触发表级别全局索引的更新,这意味着这些 DDL 操作只有在对应表的全局索引完全更新后才会返回结果。
1698-
1699- ``` sql
1700- CREATE TABLE t1 (
1701- col1 INT NOT NULL ,
1702- col2 DATE NOT NULL ,
1703- col3 INT NOT NULL ,
1704- col4 INT NOT NULL ,
1705- UNIQUE KEY uidx12(col1, col2) GLOBAL,
1706- UNIQUE KEY uidx3(col3),
1707- KEY idx1(col1) GLOBAL
1708- )
1709- PARTITION BY HASH(col3)
1710- PARTITIONS 4 ;
1711- ```
1712-
1713- 在上面示例中,唯一索引 ` uidx12 ` 和非唯一索引 ` idx1 ` 将成为全局索引,但 ` uidx3 ` 仍是常规的唯一索引。
1714-
1715- 请注意,** 聚簇索引** 不能成为全局索引,如下例所示:
1716-
1717- ``` sql
1718- CREATE TABLE t2 (
1719- col1 INT NOT NULL ,
1720- col2 DATE NOT NULL ,
1721- PRIMARY KEY (col2) CLUSTERED GLOBAL
1722- ) PARTITION BY HASH(col1) PARTITIONS 5 ;
1723- ```
1724-
1725- ```
1726- ERROR 1503 (HY000): A CLUSTERED INDEX must include all columns in the table's partitioning function
1727- ```
1728-
1729- 聚簇索引不能成为全局索引,是因为如果聚簇索引是全局索引,则表将不再分区。这是因为聚簇索引的键是分区级别的行数据的键,但全局索引是表级别的,这就造成了冲突。如果需要将主键设置为全局索引,则需要显式设置该主键为非聚簇索引,如 ` PRIMARY KEY(col1, col2) NONCLUSTERED GLOBAL ` 。
1730-
1731- 你可以通过 [ ` SHOW CREATE TABLE ` ] ( /sql-statements/sql-statement-show-create-table.md ) 输出中的 ` GLOBAL ` 索引选项来识别全局索引。
1732-
1733- ``` sql
1734- SHOW CREATE TABLE t1\G
1735- ```
1736-
1737- ```
1738- Table: t1
1739- Create Table: CREATE TABLE `t1` (
1740- `col1` int NOT NULL,
1741- `col2` date NOT NULL,
1742- `col3` int NOT NULL,
1743- `col4` int NOT NULL,
1744- UNIQUE KEY `uidx12` (`col1`,`col2`) /*T![global_index] GLOBAL */,
1745- UNIQUE KEY `uidx3` (`col3`),
1746- KEY `idx1` (`col1`) /*T![global_index] GLOBAL */
1747- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
1748- PARTITION BY HASH (`col3`) PARTITIONS 4
1749- 1 row in set (0.00 sec)
1750- ```
1751-
1752- 或查询 [ ` INFORMATION_SCHEMA.TIDB_INDEXES ` ] ( /information-schema/information-schema-tidb-indexes.md ) 表并查看输出中的 ` IS_GLOBAL ` 列来识别全局索引。
1753-
1754- ``` sql
1755- SELECT * FROM information_schema .tidb_indexes WHERE table_name= ' t1' ;
1756- ```
1757-
1758- ```
1759- +--------------+------------+------------+----------+--------------+-------------+----------+---------------+------------+----------+------------+-----------+-----------+
1760- | TABLE_SCHEMA | TABLE_NAME | NON_UNIQUE | KEY_NAME | SEQ_IN_INDEX | COLUMN_NAME | SUB_PART | INDEX_COMMENT | Expression | INDEX_ID | IS_VISIBLE | CLUSTERED | IS_GLOBAL |
1761- +--------------+------------+------------+----------+--------------+-------------+----------+---------------+------------+----------+------------+-----------+-----------+
1762- | test | t1 | 0 | uidx12 | 1 | col1 | NULL | | NULL | 1 | YES | NO | 1 |
1763- | test | t1 | 0 | uidx12 | 2 | col2 | NULL | | NULL | 1 | YES | NO | 1 |
1764- | test | t1 | 0 | uidx3 | 1 | col3 | NULL | | NULL | 2 | YES | NO | 0 |
1765- | test | t1 | 1 | idx1 | 1 | col1 | NULL | | NULL | 3 | YES | NO | 1 |
1766- +--------------+------------+------------+----------+--------------+-------------+----------+---------------+------------+----------+------------+-----------+-----------+
1767- 3 rows in set (0.00 sec)
1768- ```
1769-
1770- 在对普通表进行分区或者对分区表进行重新分区时,可以根据需要将索引更新为全局索引或局部索引。
1771-
1772- 例如,下面的 SQL 语句会基于 ` col1 ` 列对表 ` t1 ` 进行重新分区,并将该表中的全局索引 ` uidx12 ` 和 ` idx1 ` 更新为局部索引,将局部索引 ` uidx3 ` 更新为全局索引。` uidx3 ` 是基于 ` col3 ` 列的唯一索引,为了保证 ` col3 ` 在所有分区中的唯一性,` uidx3 ` 必须为全局索引;` uidx12 ` 和 ` idx1 ` 是基于 ` col1 ` 列的索引,因此可以是全局索引或局部索引。
1773-
1774- ``` sql
1775- ALTER TABLE t1 PARTITION BY HASH (col1) PARTITIONS 3 UPDATE INDEXES (uidx12 LOCAL, uidx3 GLOBAL, idx1 LOCAL);
1776- ```
1777-
1778- #### 全局索引的限制
1779-
1780- - 如果索引定义中未显式指定 ` GLOBAL ` 关键字,TiDB 将默认创建局部索引 (Local Index)。
1781- - ` GLOBAL ` 和 ` LOCAL ` 关键字仅适用于分区表,对非分区表没有影响。即在非分区表中,全局索引和局部索引之间没有区别。
1782- - 以下 DDL 操作会触发全局索引的更新:` DROP PARTITION ` 、` TRUNCATE PARTITION ` 和 ` REORGANIZE PARTITION ` 。这些 DDL 需等待全局索引更新完成后才会返回结果,耗时会相应增加。尤其是在数据归档场景下,如 ` DROP PARTITION ` 和 ` TRUNCATE PARTITION ` ,若没有全局索引,通常可以立即完成;但使用全局索引后,耗时会随着所需更新的索引数量的增加而增加。
1783- - 包含全局索引的表不支持 ` EXCHANGE PARTITION ` 。
1784- - 默认情况下,分区表的主键为聚簇索引,且必须包含分区键。如果要求主键不包含分区建,可以在建表时显式指定主键为非聚簇的全局索引,例如:` PRIMARY KEY(col1, col2) NONCLUSTERED GLOBAL ` 。
1785- - 如果在表达式列上添加了全局索引,或者一个全局索引同时也是前缀索引(如 ` UNIQUE KEY idx_id_prefix (id(10)) GLOBAL ` ),你需要为该全局索引手动收集统计信息。
1689+ 关于全局索引的详细介绍,参见[ 全局索引] ( /global-indexes.md ) 。
17861690
17871691### 关于函数的分区限制
17881692
0 commit comments