日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

如何使用全局二級索引

PolarDB-X支持全局二級索引GSI(Global Secondary Index),本文將在分庫分表語法下介紹如何創建、使用全局二級索引功能。

使用限制

在AUTO模式的分區表中,該文檔依然適用。僅創建語法需要參考CREATE TABLE(AUTO模式)。

注意事項

  • 創建GSI過程的約束

    • 不支持在單表或廣播表上創建GSI。

    • 不支持在UNIQUE GSI中通過任何方式使用前綴索引。

    • 創建索引表時必須指定索引名。

    • 創建索引表時必須指定分庫或分庫加分表組合的規則,不允許僅指定分表規則或不指定任何拆分規則。

    • 索引表的INDEX列必須包含全部拆分鍵。

    • GSI定義子句中,索引列與覆蓋列不可重復。

    • 索引表默認包含主表的全部主鍵和拆分鍵,如果沒有顯式包含在索引列中,默認添加到覆蓋列。

    • 在DRDS模式數據庫中,對主表中的每個局部索引,如果引用的所有列均包含在索引表中,默認添加該局部索引到索引表。

    • 對GSI的每個索引列,如果沒有已經存在的索引,默認單獨創建一個索引。

    • 對包含多個索引列的GSI,默認創建一個聯合局部索引,包含所有索引列。

    • 索引定義中,索引列的length參數僅用于在索引表拆分鍵上創建局部索引。

    • 建表后創建GSI時,會在GSI創建結束時自動進行數據校驗,只有通過校驗,創建GSI的DDL語句才能執行成功。

    說明

    您也可以使用CHECK GLOBAL INDEX對索引數據進行校驗或訂正。

  • Alter Table過程的約束

    語句

    是否支持變更主表拆分鍵

    是否支持變更主表主鍵(也即索引表主鍵)

    是否支持變更本地唯一索引列

    是否支持變更索引表拆分鍵

    是否支持變更Unique Index列

    是否支持變更Index列

    是否支持變更Covering列

    ADD COLUMN

    無該場景

    不支持

    無該場景

    無該場景

    無該場景

    無該場景

    無該場景

    ALTER COLUMN SET DEFAULT和ALTER COLUMN DROP DEFAULT

    不支持

    不支持

    支持

    不支持

    不支持

    不支持

    不支持

    CHANGE COLUMN

    不支持

    不支持

    支持

    不支持

    不支持

    不支持

    不支持

    DROP COLUMN

    不支持

    不支持

    僅當唯一鍵中只有1列時支持

    不支持

    不支持

    不支持

    不支持

    MODIFY COLUMN

    不支持

    不支持

    支持

    不支持

    不支持

    不支持

    不支持

    說明

    以上對列的分類存在重疊(如Index列包含索引表拆分鍵,Covering列包含主表拆分鍵、主鍵以及指定的列),若存在支持情況沖突情況,不支持的優先級高于支持。

    下表匯總了使用ALTER TABLE語句變更索引的支持情況:

    語句

    是否支持

    ALTER TABLE ADD PRIMARY KEY

    支持

    ALTER TABLE ADD [UNIQUE/FULLTEXT/SPATIAL/FOREIGN] KEY

    支持,您可以同時在主表和索引表上添加局部索引,索引名稱不可與GSI重復。

    ALTER TABLE ALTER INDEX index_name {VISIBLE | INVISIBLE}

    禁止

    ALTER TABLE {DISABLE | ENABLE} KEYS

    支持,僅在主表執行(禁止變更GSI狀態)。

    ALTER TABLE DROP PRIMARY KEY

    禁止

    ALTER TABLE DROP INDEX

    僅支持刪除普通索引或全局二級索引。

    ALTER TABLE DROP FOREIGN KEY fk_symbol

    支持,僅在主表執行。

    ALTER TABLE RENAME INDEX

    禁止

    說明

    考慮到全局二級索引的穩定性和性能情況,目前禁止直接使用DROP COLUMN命令重命名全局二級索引。如需修改全局二級索引名,您可以先使用DROP INDEX刪除對應的全局二級索引,再重新創建一個新的二級索引。

  • Alter GSI Table的約束條件

    • 不支持在索引表上執行DDL、DML語句。

    • 不支持帶有NODE HINT的DML語句更新主表、索引表。

  • 在包含GSI的表上使用其他DDL時的約束

    語句

    是否支持

    DROP TABLE

    支持

    DROP INDEX

    支持

    TRUNCATE TABLE

    不支持

    RENAME TABLE

    不支持

    ALTER TABLE RENAME

    不支持

    說明
    • 考慮主表與索引表的數據一致性,目前禁止執行TRUNCATE TABLE語句 。如需清空主表與索引表數據,您可以使用DELETE語句刪除對應的數據,或強制使用HINT /*+TDDL:CMD_EXTRA(TRUNCATE_TABLE_WITH_GSI=TRUE)*/。

    • 考慮到全局二級索引的穩定性和性能情況,目前禁止直接使用RENAME TABLE或ALTER TABLE RENAME命令重命名全局二級索引。如需修改全局二級索引名,您可以先使用DROP INDEX刪除全局二級索引,修改表名后再重新創建新的二級索引。

  • 在包含GSI的表上使用DML語句時的約束

    • 不支持在索引表上執行DML語句。

    • 在主表上執行DML語句的有如下限制:寫索引失敗后,不允許繼續執行其他語句或提交事務。

    CREATE TABLE t_order(
      `id` bigint(11) NOT NULL AUTO_INCREMENT,
      `order_id` varchar(20) DEFAULT NULL,
      `buyer_id` varchar(20) DEFAULT NULL,
      `seller_id` varchar(20) DEFAULT NULL,
      `order_snapshot` longtext DEFAULT NULL,
      `order_detail` longtext DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `l_i_order` (`order_id`),
      GLOBAL INDEX `g_i_seller` (`seller_id`) dbpartition by hash(`seller_id`) tbpartition by hash(`seller_id`),
      GLOBAL UNIQUE INDEX `g_i_buyer` (`buyer_id`) COVERING (order_snapshot) dbpartition by hash(`buyer_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by hash(`order_id`);
    
    SET DRDS_TRANSACTION_POLICY='XA';
    INSERT INTO t_order(order_id, buyer_id, seller_id) VALUES('order_1', 'buyer_1', 'seller_1');
    # 失敗
    INSERT IGNORE INTO t_order(order_id, buyer_id, seller_id) VALUES('order_2', 'buyer_1', 'seller_1');
    # 失敗不允許繼續執行
    INSERT IGNORE INTO t_order(order_id, buyer_id, seller_id) VALUES('order_2', 'buyer_2', 'seller_2');
    # 失敗后不允許提交事務
    COMMIT;

創建GSI

PolarDB-X對MySQL DDL語法進行了擴展,增加定義GSI的語法。使用方式與在MySQL上創建索引一致。

  • 建表時定義GSI定義GSI

  • 建表后添加GSI添加GSI

說明
  • 索引名:作為索引表的名字,用于創建索引表。

  • 索引列:索引表的分庫分表鍵,即索引分庫分表子句中用到的所有列。

  • 覆蓋列:索引表中的其他列,默認包含主鍵和主表的全部分庫分表鍵。

  • 索引分庫分表子句:索引表的分庫分表算法,與CREATE TABLE中分庫分表子句的語法一致。

  • 上述是在分庫分表下的創建GSI語法,如果是在分區表下GSI語法只需要可以參考CREATE TABLE(AUTO模式)。

示例:

# 建表時定義GSI
CREATE TABLE t_order (
 `id` bigint(11) NOT NULL AUTO_INCREMENT,
 `order_id` varchar(20) DEFAULT NULL,
 `buyer_id` varchar(20) DEFAULT NULL,
 `seller_id` varchar(20) DEFAULT NULL,
 `order_snapshot` longtext DEFAULT NULL,
 `order_detail` longtext DEFAULT NULL,
 PRIMARY KEY (`id`),
 GLOBAL INDEX `g_i_seller`(`seller_id`) COVERING (`id`, `order_id`, `buyer_id`, `order_snapshot`) dbpartition by hash(`seller_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 dbpartition by hash(`order_id`);
# 添加GSI
CREATE UNIQUE GLOBAL INDEX `g_i_buyer` ON `t_order`(`buyer_id`) 
    COVERING(`seller_id`, `order_snapshot`) 
    dbpartition by hash(`buyer_id`) tbpartition by hash(`buyer_id`) tbpartitions 3

使用GSI

GSI創建完成后,可以通過如下方式指定查詢使用的索引表:

  • 通過HINT指定索引

    您可以選擇以下兩種HINT語句中的任意一種指定使用目標索引進行查詢。

    • FORCE INDEX({index_name})

      示例:

      SELECT a.*, b.order_id 
       FROM t_seller a 
         JOIN t_order b FORCE INDEX(g_i_seller) ON a.seller_id = b.seller_id 
       WHERE a.seller_nick="abc";
    • /*+TDDL:INDEX({table_name/table_alias}, {index_name})*/

      示例:

      /*+TDDL:index(a, g_i_buyer)*/ SELECT * FROM t_order a WHERE a.buyer_id = 123
    說明

    如果查詢需要使用索引中未包含的列,則首先查詢索引表取得所有記錄的主鍵和主表分庫分表鍵,然后回查主表取得缺少列的值,詳細說明請參見INDEX HINT。

  • 直接查詢索引表

    如果索引表中包含了查詢需要的所有列,可以直接查詢索引表獲得結果。

  • 索引選擇

    對于帶有全局二級索引的主表查詢,PolarDB-X會自動選擇出優化器認為代價最低的索引表(目前只支持覆蓋索引選擇)。下面SQL查詢的主表是t_order,帶有seller_id等值過濾條件,同時涉及的id、order_snapshot和seller_id等列被全局二級索引g_i_seller覆蓋。選擇了覆蓋索引g_i_seller既可以不回表,又可以明確減少分表的掃描數目(seller_id是g_i_seller的拆分鍵)。通過EXPLAIN可以看到PolarDB-X優化器確實選擇了g_i_seller。

    EXPLAIN SELECT t_order.id,t_order.order_snapshot FROM t_order WHERE t_order.seller_id = 's1';
    IndexScan(tables="g_i_seller_sfL1_2", sql="SELECT `id`, `order_snapshot` FROM `g_i_seller` AS `g_i_seller` WHERE (`seller_id` = ?)")          
  • IGNORE INDEX與USE INDEX

    您可以通過以下HINT指定優化器使用或不使用某些索引。

    • IGNORE INDEX({index_name},...)

      示例:

      SELECT t_order.id,t_order.order_snapshot FROM t_order IGNORE INDEX(g_i_seller) WHERE t_order.seller_id = 's1';
    • USE INDEX({index_name},...)

      示例:

      SELECT t_order.id,t_order.order_snapshot FROM t_order USE INDEX(g_i_seller) WHERE t_order.seller_id = 's1';