全部產品
Search
文件中心

PolarDB:全域二級索引(GSI)

更新時間:Jul 06, 2024

PolarDB MySQL版支援在分區表上建立全域二級索引(Global Secondary Index,簡稱GSI)。使用全域二級索引可以實現透明分區表,即您可以像使用單表一樣使用分區表,大大減少分區鍵對分區表的使用限制。

說明
  • 全域二級索引功能當前處於灰階發布階段,如有需求,請前往配額中心,根據配額IDpolardb_mysql_gsi找到配額名稱,在對應的操作列單擊申請來開通該功能。

  • 如需瞭解更多關於全域二級索引(GSI)的內容,請搜尋DingTalk群號加群進行諮詢。DingTalk群號:24490017825。

背景資訊

分區表上傳統的索引為局部索引。局部索引對於邏輯表而言也是分區的,局部索引的分區方式與表的分區方式相同。局部索引單個分區的資料由分區表單個分區的資料構建而成,且局部索引的分區與分區表的分區一一對應,所以,局部索引的索引資料只能保證在單個分區內有序,如果您想建立局部唯一索引,則索引欄位必須包含全部的分區鍵。

當分區表上只存在局部索引時,使用分區表因受到分區鍵的限制,會遇到一些棘手的問題,如下:

  • 查詢條件不包含分區鍵時,查詢資料需要掃描分區表上的所有分區,這將帶來明顯的讀放大問題,且分區越多,讀放大越嚴重。

  • 查詢結果對索引欄位有順序要求時,即使局部索引中每個分區的資料是有序的,也無法保證跨分區查詢的索引資料全域有序,可能會觸發額外的全域排序操作。

  • 局部唯一索引必須包含全部的分區鍵,否則無法保證所有分區的全域唯一性限制式。

PolarDB MySQL版的全域索引與局部索引相對,全域索引不分區,由全部分區的資料構建而成。所以,全域索引上的索引資料對全域的分區表有序,如果您想建立全域唯一索引,索引欄位不需要包含全部的分區鍵。

前提條件

叢集版本需為PolarDB MySQL版8.0.2版本且修訂版本為8.0.2.2.7及以上。您可以通過查詢版本號碼來確認叢集版本。

使用限制

  • 全域二級索引僅支援在InnoDB引擎上建立的分區表,不支援混合分區表。

  • 全域二級索引不能為全文索引或空間索引。

  • 不支援在壓縮表、暫存資料表、加密表、REDUNDANT以及COMPRESSED行格式的表上建立全域二級索引。

  • 建立全域二級索引的列不能為分區表的主鍵。

  • 建立全域二級索引的表不支援產生列(Generated Column)。

  • 分區層級的DDL變更(新增RANGE或LIST分區除外)會導致已建立的全域二級索引失效,您需要先刪除表上所有的全域二級索引,再重建二級索引,或直接使用UPDATE GLOBAL INDEX文法重建二級索引。

增強特性

  • 支援使用並行DDL來並行建立全域二級索引。

  • 支援在已建立全域二級索引的分區表上使用秒級加欄位功能。

  • 已建立全域二級索引的RANGE或LIST分區表,在新增分區時支援使用分區層級的MDL鎖。

  • 支援將已建立全域二級索引的錶轉換為INTERVAL RANGE分區表,同時支援在INTERVAL RANGE分區表上建立全域二級索引。

  • 對已建立全域二級索引的分區表執行分區層級的DDL變更時,支援使用UPDATE GLOBAL INDEX文法重建表上的全域二級索引。樣本如下:

    1. 建立以a欄位為分區鍵的RANGE分區表t1,同時在b欄位上建立全域索引k1

      CREATE TABLE t1(
        a INT PRIMARY KEY,
        b INT,
        INDEX k1(b) GLOBAL
      ) PARTITION BY RANGE (`a`)
      (PARTITION p0 VALUES LESS THAN (5) ENGINE = InnoDB,
       PARTITION p1 VALUES LESS THAN (10) ENGINE = InnoDB);
    2. 刪除t1表上的p1分區並重建全域二級索引。

      ALTER TABLE t1 DROP PARTITION p1 UPDATE GLOBAL INDEX;

文法

建立索引時,通過在索引名稱後添加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命令時,使用全域二級索引的執行耗時較短,且資料量越大執行耗時差異越明顯。