PolarDB MySQL版支援在分區表上建立全域二級索引(Global Secondary Index,簡稱GSI)。使用全域二級索引可以實現透明分區表,即您可以像使用單表一樣使用分區表,大大減少分區鍵對分區表的使用限制。
全域二級索引功能當前處於灰階發布階段,如有需求,請前往配額中心,根據配額ID
polardb_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
文法重建表上的全域二級索引。樣本如下:建立以
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);
刪除
t1
表上的p1
分區並重建全域二級索引。ALTER TABLE t1 DROP PARTITION p1 UPDATE GLOBAL INDEX;
文法
建立索引時,通過在索引名稱後添加LOCAL或GLOBAL關鍵字來指定局部索引或全域索引。
如果在建立索引時,沒有指定全域二級索引,則預設建立局部索引。
樣本
建立以
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
,再在t1
的b
欄位上建立全域索引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_1
和mytest2.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;
測試方法
針對SELECT、UPDATE和DELETE語句的查詢條件中不包含分區鍵的情境,測試不同分區數量下,使用局部索引和全域索引的耗時。
測試結果
SELECT語句的查詢條件中不包含分區鍵,使用局部索引和全域索引的耗時。
UPDATE語句的查詢條件中不包含分區鍵,使用局部索引和全域索引的耗時。
DELETE語句的查詢條件中不包含分區鍵,使用局部索引和全域索引的耗時。
由以上的測試結果可以看出:在查詢條件不包含分區鍵的情境中,執行SELECT、UPDATE和DELETE命令時,使用全域二級索引的執行耗時較短,且資料量越大執行耗時差異越明顯。