全局二级索引(GSI)

PolarDB MySQL版支持在分区表上创建全局二级索引(Global Secondary Index,简称GSI)。使用全局二级索引可以实现透明分区表,即您可以像使用单表一样使用分区表,大大减少分区键对分区表的使用限制。

说明

全局二级索引功能当前处于灰度发布阶段,如有需求,请提交申请申请使用权限。

背景信息

分区表上传统的索引为局部索引。局部索引对于逻辑表而言也是分区的,局部索引的分区方式与表的分区方式相同。局部索引单个分区的数据由分区表单个分区的数据构建而成,且局部索引的分区与分区表的分区一一对应,所以,局部索引的索引数据只能保证在单个分区内有序,如果您想创建局部唯一索引,则索引字段必须包含全部的分区键。

当分区表上只存在局部索引时,使用分区表因受到分区键的限制,会遇到一些棘手的问题,如下:

  • 查询条件不包含分区键时,查询数据需要扫描分区表上的所有分区,这将带来明显的读放大问题,且分区越多,读放大越严重。

  • 查询结果对索引字段有顺序要求时,即使局部索引中每个分区的数据是有序的,也无法保证跨分区查询的索引数据全局有序,可能会触发额外的全局排序操作。

  • 局部唯一索引必须包含全部的分区键,否则无法保证所有分区的全局唯一性约束。

PolarDB MySQL版的全局索引与局部索引相对,全局索引不分区,由全部分区的数据构建而成。所以,全局索引上的索引数据对全局的分区表有序,如果您想创建全局唯一索引,索引字段不需要包含全部的分区键。

前提条件

集群版本需为PolarDB MySQL版8.0.2版本且修订版本为8.0.2.2.7及以上。您可以通过查询版本号来确认集群版本。

使用限制

  • 全局二级索引仅支持在InnoDB引擎上创建的分区表,不支持混合分区表。

  • 全局二级索引不能为全文索引或空间索引。

  • 不支持在压缩表、临时表、加密表、REDUNDANT以及COMPRESSED行格式的表上创建全局二级索引。

  • 创建全局二级索引的列不能为分区表的主键。

  • 创建全局二级索引的表不支持生成列(Generated Column)。

  • 创建全局二级索引的表不支持秒级加字段。

语法

创建索引时,通过在索引名称后添加LOCALGLOBAL关键字来指定局部索引或全局索引。

说明

如果在创建索引时,没有指定全局二级索引,则默认创建局部索引。

示例

  • 创建以a字段为分区键的分区表t1。同时在b字段上创建全局索引k1

    CREATE TABLE t1(
      a INT PRIMARY KEY,
      b INT,
      INDEX k1(b) GLOBAL
    ) PARTITION BY HASH(a) PARTITIONS 3;
  • 创建以a字段为分区键的分区表t1,再在t1b字段上创建全局索引k1和全局唯一索引k2

    CREATE TABLE t1(
      a INT PRIMARY KEY,
      b INT
    ) PARTITION BY HASH(a) PARTITIONS 3;
    
    ALTER TABLE t1 ADD INDEX k1(b) GLOBAL;
    
    CREATE UNIQUE INDEX k2 ON t1(b) GLOBAL;

性能测试

测试对象

数据量100万条,表结构和表数据相同的2张分区表。在1张分区表上创建局部索引,另外的1张分区表上创建全局二级索引。

此处以创建分区表mytest1.big_table_1mytest2.big_table_1为例,其中,表mytest1.big_table_1为创建局部索引的表,表mytest2.big_table_1为创建全局二级索引的表。

CREATE TABLE mytest1.big_table_1(
  a INT PRIMARY KEY,
  b INT,
  c INT,
  INDEX k1(b) LOCAL
) PARTITION BY HASH(a) PARTITIONS 32;

CREATE TABLE mytest2.big_table_1(
  a INT PRIMARY KEY,
  b INT,
  c INT,
  INDEX k1(b) GLOBAL
) PARTITION BY HASH(a) PARTITIONS 32;

测试方法

针对SELECTUPDATEDELETE语句的查询条件中不包含分区键的场景,测试不同分区数量下,使用局部索引和全局索引的耗时。

测试结果

  • SELECT语句的查询条件中不包含分区键,使用局部索引和全局索引的耗时。image

  • UPDATE语句的查询条件中不包含分区键,使用局部索引和全局索引的耗时。image

  • DELETE语句的查询条件中不包含分区键,使用局部索引和全局索引的耗时。image

由以上的测试结果可以看出:在查询条件不包含分区键的场景中,执行SELECTUPDATEDELETE命令时,使用全局二级索引的执行耗时较短,且数据量越大执行耗时差异越明显。

阿里云首页 云原生数据库 PolarDB MySQL版 相关技术圈