全部产品
Search
文档中心

PolarDB:FORCE INDEX

更新时间:Jul 03, 2025

Topik ini menjelaskan batasan dan penggunaan FORCE INDEX di PolarDB-X.

Informasi latar belakang

PolarDB-X mendukung indeks sekunder global dan indeks lokal. Indeks lokal dapat dibuat langsung pada tabel atau sebagai partisi indeks dari indeks sekunder global. PolarDB-X memperluas fungsionalitas FORCE INDEX dan USE INDEX di MySQL dengan menambahkan dukungan untuk indeks dua tingkat, yang berarti Anda dapat menentukan baik indeks global maupun lokal dalam petunjuk (hints).

Versi yang didukung

  • Jika versi node komputasi lebih awal dari 5.4.18, hanya indeks satu tingkat yang didukung.

  • Jika versi node komputasi adalah 5.4.18 dan versi minor lebih awal dari 1718157, hanya indeks satu tingkat yang didukung.

  • Jika versi node komputasi adalah 5.4.18 dan versi minor adalah 1718157 atau lebih baru, indeks dua tingkat didukung.

  • Jika versi node komputasi adalah 5.4.19 dan tanggal rilis lebih awal dari 10 Juli 2024, hanya indeks satu tingkat yang didukung.

  • Jika versi node komputasi adalah 5.4.19 dan tanggal rilis adalah 10 Juli 2024 atau lebih baru, indeks dua tingkat didukung.

  • Jika versi node komputasi lebih baru dari 5.4.19, indeks dua tingkat didukung.

Catatan

Catatan penggunaan

  • Saat menggunakan FORCE INDEX atau INDEX HINT, Anda harus menentukan indeks dengan nama lengkapnya. Pencocokan awalan tidak didukung.

  • Indeks lokal yang ditentukan akan dipaksa digunakan jika kondisi berikut terpenuhi:

    • Ini adalah partisi indeks dari indeks sekunder global yang dipilih oleh optimizer berdasarkan estimasi biaya.

    • Catatan: Indeks sekunder global yang tidak mengandung partisi indeks lokal yang ditentukan tidak akan dipilih.

  • Saat FORCE INDEX (PRIMARY) digunakan, semua indeks sekunder global tidak akan dipilih.

Sintaksis

Indeks satu tingkat

# FORCE INDEX
tbl_name [[AS] alias] [index_hint]
index_hint:
    FORCE INDEX({gsi_name|local_index_name|primary})

# INDEX HINT
/*+TDDL: INDEX({table_name|table_alias}, {local_index_name|gsi_name|primary})*/
Catatan

Parameter

  • gsi_name: nama indeks sekunder global.

  • local_index_name: nama indeks lokal.

  • primary: kunci utama.

Indeks dua tingkat

# FORCE INDEX
tbl_name [[AS] alias] [index_hint]
index_hint:
    FORCE INDEX(gsi_name[.{local_index_name|primary}] | local_index_name | primary[.{local_index_name|primary}])

# INDEX HINT
/*+TDDL: INDEX({table_name|table_alias}, {local_index_name|gsi_name|primary} [, {local_index_name|primary}])*/
Catatan

Parameter

  • gsi_name: nama indeks sekunder global.

  • local_index_name: nama indeks lokal.

  • primary: kunci utama.

Contoh

CREATE TABLE `t_order` (
	`id` bigint(11) NOT NULL AUTO_INCREMENT,
	`order_id` varchar(20) NOT NULL,
	`buyer_id` varchar(20) DEFAULT NULL,
	`seller_id` varchar(20) DEFAULT NULL,
	PRIMARY KEY (`id`),
	GLOBAL INDEX `g_i_buyer` (`buyer_id`) COVERING (`order_id`)
		PARTITION BY KEY(`buyer_id`)
		PARTITIONS 16,
	GLOBAL INDEX `g_i_seller` (`seller_id`) COVERING (`order_id`)
		PARTITION BY KEY(`seller_id`)
		PARTITIONS 16,
	KEY `l_i_order` (`order_id`),
	KEY `l_i_buyer` (`buyer_id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8
PARTITION BY KEY(`order_id`)
PARTITIONS 16

Indeks satu tingkat

Tentukan indeks lokal l_i_order dalam FORCE INDEX:

mysql> EXPLAIN SELECT * FROM T_ORDER FORCE INDEX(l_i_order);
+---------------------+
| LOGICAL EXECUTIONPLAN
+---------------------+
| Gather(concurrent=true)
|   LogicalView(tables="t_order[p1,p2,p3,...p16]", shardCount=16, sql="SELECT `id`, `order_id`, `buyer_id`, `seller_id` FROM `T_ORDER` AS `T_ORDER` FORCE INDEX(L_I_ORDER)") 
| HitCache:false   
| Source:PLAN_CACHE
| TemplateId: 3d1b35fa  
+---------------------+

Tentukan indeks sekunder global g_i_buyer dalam INDEX HINT:

mysql> EXPLAIN /*TDDL:INDEX(T_ORDER, g_i_buyer)*/ SELECT * FROM T_ORDER;
+---------------------+
| LOGICAL EXECUTIONPLAN
+---------------------+
| Project(id="id", order_id="order_id", buyer_id="buyer_id", seller_id="seller_id") 
|   BKAJoin(condition="id = id AND order_id = order_id", type="inner")        
|     Gather(concurrent=true)           
|       IndexScan(tables="g_i_buyer_$27c2[p1,p2,p3,...p16]", shardCount=16, sql="SELECT `id`, `order_id`, `buyer_id` FROM `g_i_buyer_$27c2` AS `g_i_buyer_$27c2`") 
|     Gather(concurrent=true)           
|       LogicalView(tables="t_order[p1,p2,p3,...p16]", shardCount=16, sql="SELECT `id`, `order_id`, `seller_id` FROM `T_ORDER` AS `T_ORDER` FORCE INDEX(PRIMARY) WHERE (((`id`, `order_id`)) IN (...))") 
| HitCache:false                        
| Source:null                           
| TemplateId: NULL                      
+---------------------+

Indeks dua tingkat

Tentukan indeks lokal auto_shard_key_buyer_id, yang merupakan bagian dari indeks sekunder global g_i_buyer, dalam FORCE INDEX:

mysql> EXPLAIN SELECT * FROM T_ORDER FORCE INDEX(g_i_buyer.auto_shard_key_buyer_id);
+---------------------+
| LOGICAL EXECUTIONPLAN                 
+---------------------+
| Project(id="id", order_id="order_id", buyer_id="buyer_id", seller_id="seller_id")
|   BKAJoin(condition="id = id AND order_id = order_id", type="inner")
|     Gather(concurrent=true)              
|       IndexScan(tables="g_i_buyer_$27c2[p1,p2,p3,...p16]", shardCount=16, sql="SELECT `id`, `order_id`, `buyer_id` FROM `g_i_buyer_$27c2` AS `g_i_buyer_$27c2` FORCE INDEX(AUTO_SHARD_KEY_BUYER_ID)")  
|     Gather(concurrent=true)           
|       LogicalView(tables="t_order[p1,p2,p3,...p16]", shardCount=16, sql="SELECT `id`, `order_id`, `seller_id` FROM `T_ORDER` AS `T_ORDER` FORCE INDEX(PRIMARY) WHERE (((`id`, `order_id`)) IN (...))") 
| HitCache:false                        
| Source:PLAN_CACHE                     
| TemplateId: ae278c70                  
+---------------------+

Gunakan INDEX HINT untuk menentukan indeks lokal auto_shard_key_seller_id, yang merupakan bagian dari indeks sekunder global g_i_seller pada tabel dengan nama panggilan t1, dan indeks lokal L_I_ORDER pada tabel dengan nama panggilan t2.

mysql> EXPLAIN /*TDDL:index(t1, g_i_seller, auto_shard_key_seller_id) index(t2, primary, L_I_ORDER)*/ SELECT * FROM t_order t1 join t_order t2 on t1.id=t2.id where t1.buyer_id = '123456';
+---------------------+
| LOGICAL EXECUTIONPLAN                                         
+---------------------+
| BKAJoin(condition="id = id", type="inner")                    
|   Project(id="id", order_id="order_id", buyer_id="buyer_id", seller_id="seller_id")
|     BKAJoin(condition="id = id AND order_id = order_id", type="inner")
|       Gather(concurrent=true)                                 
|         IndexScan(tables="g_i_seller_$3e3d[p1,p2,p3,...p16]", shardCount=16, sql="SELECT `id`, `order_id`, `seller_id` FROM `g_i_seller_$3e3d` AS `g_i_seller_$3e3d` FORCE INDEX(AUTO_SHARD_KEY_SELLER_ID)")                   
|       Gather(concurrent=true)                                 
|         LogicalView(tables="t_order[p1,p2,p3,...p16]", shardCount=16, sql="SELECT `id`, `order_id`, `buyer_id` FROM `t_order` AS `t_order` FORCE INDEX(PRIMARY) WHERE ((`buyer_id` = ?) AND (((`id`, `order_id`)) IN (...)))") 
|   Gather(concurrent=true)                                     
|     LogicalView(tables="t_order[p1,p2,p3,...p16]", shardCount=16, sql="SELECT `id`, `order_id`, `buyer_id`, `seller_id` FROM `t_order` AS `t_order` FORCE INDEX(L_I_ORDER) WHERE (`id` IN (...))")                             
| HitCache:false                                                
| Source:null                                                   
| TemplateId: NULL                                              
+---------------------+