---
title: 为什么创建的 global index（全局索引）会自动变成 local index（本地索引）？-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于 为什么创建的 global index（全局索引）会自动变成 local index（本地索引）？相关的常见问题和使用技巧，帮助您快速解决 为什么创建的 global index（全局索引）会自动变成 local index（本地索引）？的难题。
image: https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*OSPzQ6GUQF4AAAAAQHAAAAgAeiGDAQ/original
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

划线反馈

# 为什么创建的 global index（全局索引）会自动变成 local index（本地索引）？

更新时间：2024-10-17 02:07

适用版本： V4.2.x 内容类型：FAQ  

## 问题一：在一张非分区表上，创建 global index（全局索引），在 ODC 中被展示成了本地索引（local index），是否非分区表上的 global index（全局索引）都会被转换为 local index（本地索引）？

```shell
-- 创建测试表 t1。
create table t1(c1 int, unique index g_idx(c1) global);

-- 通过 ODC 查看表定义的 DDL，可能会是如下结果。

CREATE TABLE `t1` (
  `c1` int(11) DEFAULT NULL,
  UNIQUE KEY `g_idx` (`c1`) LOCAL
)

```

由于 ODC 老版本存在 BUG，如果遇到的话，直接更新 ODC 到最新版本。

### 为什么即使 ODC 在这种情况下把索引的 global 属性改成 local 属性，也不会有任何问题？

local 索引的定义：索引必须和主表的分区方式完全相同。

global 索引的定义：可以和主表的分区方式不同或者相同。当创建一个不显式指定索引分区规则的 global index（全局索引），索引就会被默认的创建为非分区索引（只有一个分区的索引），如果主表也是非分区表（只有一个分区的表），表和索引的分区方式一致，都是单分区，那么就等价于创建了一个 local index（本地索引）也就是和主表分区方式一致的索引。所以，在非分区表上，创建一个不显式指定分区规则 global index（全局索引），其实和创建一个 local index（本地索引）是没有实质区别的。

综上论述可知非分区表上的 global index（全局索引）不会都会被转换为 local index（本地索引），因为 global index（全局索引）也可以有自己独立于主表的分区方式，例如下面这种 DDL，主表是非分区表，global index（全局索引）是分区表，那么就不能随意将 global index（全局索引） 改成 local index（本地索引），否则就会有正确性问题。

```shell
-- 建表 DDL
create table t2(c1 int, unique index g_idx(c1) global partition by hash(c1));

-- 通过 ODC 查看表定义的 DDL，可能会是如下结果：
CREATE TABLE `t2` (
  `c1` int(11) DEFAULT NULL,
  UNIQUE KEY `g_idx` (`c1`) BLOCK_SIZE 16384 GLOBAL
 partition by hash(c1)
(partition `p0`)
)

```

## 问题二：如何通过 SQL 来判断整个 OceanBase 数据库里的哪些索引是 global 属性的，哪些是 local 属性的？

因为 global 索引不是和 MySQL 兼容的功能，冒然在 MySQL 兼容视图例如 statistics 上加字段，可能会导致 MySQL 生态工具的兼容性问题，所以 OceanBase 在 MySQL 模式下暂时还没有提供相关的字典视图，可通过内部表 `__all_virtual_table`（非官方提供的方案）。

在 sys 租户下查的话，可以查到所有租户的所有表的元信息，若在用户租户下查的话，可以查到当前租户的所有表的元信息。

```shell
-- 在 sys 租户下查。
select distinct(tenant_id) from oceanbase.__all_virtual_table;

```

输出结果如下：

```shell
+-----------+
| tenant_id |
+-----------+
|         1 |
|      1001 |
|      1002 |
+-----------+
3 rows in set (0.045 sec)

```

```shell
-- 在用户租户下查
select distinct(tenant_id) from oceanbase.__all_virtual_table;

```

输出结果如下：

```shell
+-----------+
| tenant_id |
+-----------+
|      1002 |
+-----------+
1 row in set (0.043 sec)

```

#### 注意

由于内部表 `__all_virtual_table` 非字典视图，不保证所有字段都能够向后兼容，若遇字典视图实在查不出相应的信息，否则不推荐直接查这张表。

比如查询在用户租户下执行下面这条 SQL，就可以查出当前租户的所有 `unique global index`。

```shell
SELECT b.table_name data_table_name,
       substr(a.table_name, 7 + instr(substr(a.table_name, 7), '_')) index_name
FROM oceanbase.__all_virtual_table a,
     oceanbase.__all_virtual_table b
WHERE a.data_table_id = b.table_id
  AND (a.index_type = 4
       OR a.index_type = 8);

```

输出结果如下：

```shell
+-----------------+------------+
| data_table_name | index_name |
+-----------------+------------+
| t1              | g_idx      |
| t2              | g_idx      |
+-----------------+------------+
2 rows in set (0.048 sec)

```

SQL 语句中涉及内部表 `__all_virtual_table` 的字段 `data_table_id` 含义： `data_table_id` 主表和索引表都会在 `__all_virtual_table` 中占据一行，索引表的 `data_table_id` 字段就是其主表的 table_id，所以通过 a.data_table_id = b.table_id 关联主表和索引表。

另外该 SQL 语句对索引表的 table_name 做 substr，因为这张内部表里记录的索引表的 table_name 的原始信息是为 __idx_主表id_索引表名，如下所示。

```shell
SELECT
  b.table_id data_table_id,
  a.table_id index_table_id,
  b.table_name data_table_name,
  a.table_name index_name
FROM oceanbase.__all_virtual_table a,
     oceanbase.__all_virtual_table b
WHERE a.data_table_id = b.table_id
  AND (a.index_type = 4
       OR a.index_type = 8);

```

输出结果如下：

```shell
+---------------+----------------+-----------------+--------------------+
| data_table_id | index_table_id | data_table_name | index_name         |
+---------------+----------------+-----------------+--------------------+
|        500077 |         500078 | t1              | __idx_500077_g_idx |
|        500079 |         500080 | t2              | __idx_500079_g_idx |
+---------------+----------------+-----------------+--------------------+
2 rows in set (0.046 sec)

```

上述 SQL 语句中过滤条件 `index_type = 4 OR a.index_type = 8` 有关 `index_type` 的含义，可参见 github 中 [ob_schema_struct](https://github.com/oceanbase/oceanbase/blob/develop/src/share/schema/ob_schema_struct.h) 的 ObIndexType 定义部分，相应的标注如下。 ![image](https://obbusiness-private.oss-cn-shanghai.aliyuncs.com/doc/img/knowledge-base/database/sql/20240926globallocalindex001.jpg)

`index_type = 8` 的 index 应该就是普通的 `unique global index`，`index_type = 8` 的 index 应该是第一个问题中 `unique local index` 退化成 `unique global index`。

## 适用版本

OceanBase 数据库 V4.2.x 版本。

上一篇

[JSON 多值索引的使用说明](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000002342355)

下一篇

[查询每张表的大小及其索引大小](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000003083034) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
