本文中含有需要您注意的重要提示信息,忽略該信息可能對您的業務造成影響,請務必仔細閱讀。
本文檔向您介紹PolarDB-X的索引診斷功能,您可以使用此功能診斷和發現數據庫中低效的索引,進而采取措施提升數據庫的性能。
背景信息
“建立索引”是數據庫中加速查詢的常用手段,可以顯著提高查詢效率。但索引會在數據表更新的時候同步更新,因此索引會降低寫入效率。此外,索引還會占用數據庫的存儲空間。因此,您需要合理使用索引,避免建立過多數量的或不必要的索引。
PolarDB-X的索引診斷功能,可以幫助您發現數據庫中不必要的、低效的索引(包括局部索引和全局二級索引),并給出優化建議幫助您對相關索引做出必要調整(刪除或重建),從而在不影響查詢性能的前提下,提升寫入性能,節約存儲空間。
為使得您的數據庫保持良好性能,建議您定期進行索引診斷。
前提條件
本功能支持PolarDB-X的5.4.17-16859297及以上版本。查看實例版本的方法請參見查看和升級實例版本。
注意事項
索引診斷功能同時支持AUTO模式數據庫與DRDS模式數據庫。
語法
INSPECT [FULL] INDEX [FROM table_name] [MODE= {STATIC|DYNAMIC|MIXED}]
參數說明
MODE:診斷模式,支持3種診斷模式,不設置MODE參數時,默認為STATIC模式。
FROM:需要診斷的數據表。
不附加FROM選項時,默認對當前數據庫中所有表的索引進行診斷。
附加FROM選項時,僅對指定的數據表進行診斷。
FULL:輸出信息的詳細程度。
附加FULL選項時,會輸出索引的詳細診斷結果,包括存在的問題和建議。
不附加FULL選項時,僅輸出建議。
STATIC模式
執行以下命令,創建表tb1。
create table tb1(
id int,
name varchar(20),
code varchar(50),
primary key(id),
global index idx_name(`name`) partition by key(name),
global index idx_name_code(`name`, `code`) partition by key(name, code),
global index idx_id(`id`) partition by key(id)
) partition by key(id);
執行inspect full index from tb1\G
,返回STATIC模式的診斷結果。
inspect full index from tb1\G
*************************** 1. row ***************************
SCHEMA: d5
TABLE: tb1
INDEX: idx_id
INDEX_TYPE: GLOBAL INDEX
INDEX_COLUMN: id
COVERING_COLUMN:
USE_COUNT: 0
LAST_ACCESS_TIME: NULL
DISCRIMINATION: 0.0
PROBLEM: ineffective gsi `idx_id` because it has the same rule as primary table
ADVICE (STEP1): alter table `tb1` alter index `idx_id` invisible;
ADVICE (STEP2): alter table `tb1` drop index `idx_id`;
alter table `tb1` add local index `idx_id` (`id`);
*************************** 2. row ***************************
SCHEMA: d5
TABLE: tb1
INDEX: idx_name
INDEX_TYPE: GLOBAL INDEX
INDEX_COLUMN: name
COVERING_COLUMN: id
USE_COUNT: 0
LAST_ACCESS_TIME: NULL
DISCRIMINATION: 0.0
PROBLEM: index columns duplicate: idx_name, idx_name_code;
ADVICE (STEP1): alter table `tb1` alter index `idx_name` invisible;
ADVICE (STEP2): alter table `tb1` drop index `idx_name`;
alter table `tb1` add local index `idx_name` (`name`);
*************************** 3. row ***************************
SCHEMA: d5
TABLE: tb1
INDEX: idx_name_code
INDEX_TYPE: GLOBAL INDEX
INDEX_COLUMN: name,code
COVERING_COLUMN: id
USE_COUNT: 0
LAST_ACCESS_TIME: NULL
DISCRIMINATION: 0.0
PROBLEM: None
ADVICE (STEP1): None
ADVICE (STEP2): None
3 rows in set (0.42 sec)
診斷結果說明如下:
PROBLEM欄輸出了當前索引存在的問題。
全局索引idx_id的問題:分區方式和主表完全一致,這種全局索引無法提升查詢性能,是低效索引。
全局索引idx_name的問題:索引列和索引idx_name_code有重復(idx_name_code的索引列包含了idx_name的索引列),所以idx_name是一個冗余的索引。
ADVICE欄輸出了2個步驟的優化建議(根據不同情況,優化建議會有變化)。
返回信息中的step1,建議您使用invisible index語句隱藏此問題索引。這會使得該索引對優化器不可見,從而讓您的業務SQL在執行時繞過該索引。隱藏索引后,可以在不真正刪除問題索引的情況下,評估刪除該索引對業務帶來的影響。
說明關于invisible index功能以及如何評估業務影響,請參見INVISIBLE INDEX。
返回信息中的step2,PolarDB-X輸出的建議可能包括:直接刪除問題索引、刪除問題索引并新建一個更優的索引。
警告為避免對業務造成影響,在刪除索引之前,請務必先通過隱藏索引評估能否真正刪除此問題索引。
DYNAMIC模式
DYNAMIC模式的診斷需要依據索引的使用數據,建議收集一個完整的業務流量周期的數據(如1天、1周,這取決于您的業務特點)后再進行診斷。
使用方法
執行
set global GSI_STATISTICS_COLLECTION=true
,開啟數據庫的“索引使用信息統計”開關,收集一段時間數據。執行
inspect full index mode=dynamic\G
,進行DYNAMIC模式的索引診斷。開啟GSI_STATISTICS_COLLECTION開關會輕微影響數據庫的查詢性能(查詢性能將下降1%左右),在完成診斷后,執行
set global GSI_STATISTICS_COLLECTION=false
關閉該選項。
使用場景
在業務壓測階段提升壓測性能。業務壓測開始前,通過DYNAMIC模式診斷,識別出低效索引,根據索引診斷建議進行調整,然后再正式壓測。
在應用運行期間優化應用性能。收集索引使用的信息,等待一個完整的業務流量周期后,通過DYNAMIC模式診斷,對索引進行調整,優化應用性能。
其它
為方便您對全局索引進行調優,PolarDB-X提供了INFORMATION_SCHEMA.GLOBAL_INDEXES視圖,方便查看PolarDB-X的全局索引的使用情況。
執行以下命令,查看全局索引使用情況:
select * from information_schema.global_indexes where table="tb1"\G
*************************** 1. row ***************************
SCHEMA: testdb
TABLE: tb1
NON_UNIQUE: 1
KEY_NAME: idx_id_$3449
INDEX_NAMES: id
COVERING_NAMES:
INDEX_TYPE: NULL
DB_PARTITION_KEY:
DB_PARTITION_POLICY:
DB_PARTITION_COUNT: NULL
TB_PARTITION_KEY:
TB_PARTITION_POLICY:
TB_PARTITION_COUNT: NULL
STATUS: PUBLIC
SIZE_IN_MB: 10.03
USE_COUNT: 5
LAST_ACCESS_TIME: 2023-06-08 10:06:33
CARDINALITY: 389090
ROW_COUNT: 404508
*************************** 2. row ***************************
SCHEMA: testdb
TABLE: tb1
NON_UNIQUE: 1
KEY_NAME: idx_name_code_$2986
INDEX_NAMES: name, code
COVERING_NAMES: id
INDEX_TYPE: NULL
DB_PARTITION_KEY:
DB_PARTITION_POLICY:
DB_PARTITION_COUNT: NULL
TB_PARTITION_KEY:
TB_PARTITION_POLICY:
TB_PARTITION_COUNT: NULL
STATUS: PUBLIC
SIZE_IN_MB: 0.03
USE_COUNT: 15
LAST_ACCESS_TIME: 2023-06-08 10:10:06
CARDINALITY: -1
ROW_COUNT: 404508
2 rows in set (0.10 sec)
返回信息說明:
SIZE_IN_MB:索引占用的空間。
USE_COUNT:自您開啟GSI_STATISTICS_COLLECTION后,索引被使用的次數。
LAST_ACCESS_TIME:自您開啟GSI_STATISTICS_COLLECTION后,索引最后一次被使用的時間。
CARDINALITY:索引的基數。
ROW_COUNT:索引的行數。