本文介紹了自動索引推薦功能的背景信息以及使用方法等內容。
前提條件
支持的PolarDB PostgreSQL版的版本如下:
PostgreSQL 14(內核小版本14.10.19.0及以上)
您可通過如下語句查看PolarDB PostgreSQL版的內核小版本的版本號:
select version();
背景信息
數據庫性能優化往往是數據庫管理的關鍵任務之一,而對于SQL查詢的性能提升,索引起著至關重要的作用。合理的索引可以使得數據庫快速定位到表中特定的行,直接獲取到已經排序好的數據,極大縮短查詢時間。
不過,并非所有索引都能有效提升性能。一個合適的索引能夠大幅提升查詢速度,而不恰當的索引不僅無法提升性能,反而可能由于維護索引本身的開銷而降低數據庫的整體性能。此外,索引還占用存儲空間,過多的無效索引會浪費存儲資源。因此,確定何時以及在哪些列上創建索引是一個技術性和經驗性都很強的領域,這通常需要深入分析查詢的執行路徑和數據的分布特征。
為了協助用戶解決這一技術難題并優化數據庫的性能,PolarDB PostgreSQL版推出自動索引推薦功能。該功能可以簡化索引的創建流程,降低開發和維護數據庫索引的難度。用戶僅需通過EXPLAIN
命令對慢SQL語句進行性能分析,系統便能基于該分析提供合適的索引創建建議,并估計出預期的查詢加速效果。
自動索引推薦功能的主要優勢如下:
精準推薦:利用數據庫自動搜集的統計信息和優化器代價模型,能夠為具體的SQL查詢推薦合適的索引配置,避免了盲目地添加索引可能帶來的性能負擔和試錯成本。
效率提升:減少手動分析慢查詢的時間,幫助快速識別并針對性地解決性能瓶頸,縮短問題定位和解決的周期。
易于操作:通過一個簡單的
EXPLAIN
命令就能獲得索引推薦信息,同時提供創建索引的SQL命令以及相應的性能提升預測,優化了用戶后續操作流程。
使用指南
如果發現推薦的索引效果不符合預期或沒有推薦出合適的索引,請聯系我們進行排查優化。
以下操作建議使用psql客戶端,因為DMS客戶端目前不會展示notice提示。
配置自動索引推薦
設置所有用戶加載
polar_advisor
,即在session_preload_libraries
中增加polar_advisor
。-- session_preload_libraries默認為空,此處添加polar_advisor alter role all set session_preload_libraries to 'polar_advisor';
設置所有用戶在特定節點上開啟索引推薦,推薦僅在RO節點開啟,避免消耗RW節點的計算資源。
-- 設置在RO節點上開啟索引推薦【推薦】 alter role all set polar_advisor_type to 'index(ro)';
-- 設置在所有節點上開啟索引推薦 alter role all set polar_advisor_type to 'index';
使用自動索引推薦
使用不帶ANALYZE
語句的EXPLAIN
命令為慢SQL生成執行計劃,自動索引推薦將會自動運行,檢測到推薦的索引后會自動輸出,包括如下信息:
advise:創建推薦索引的命令。
old cost:原計劃即現在計劃的cost。
new cost:預估的創建推薦索引后的計劃的cost。
saved cost:新計劃較老計劃節省的cost。
estimate:預估的加速效果。
自動索引推薦現在能識別以下類型的算子,目前僅支持推薦BTREE索引,示例如下。
構造表及數據。
create table t( a int,b int);
insert into t select i,i from generate_series(1,10000)i;
analyze t;
根據等值條件推薦單列索引。
/*FORCE_SLAVE*/ explain select * from t where a = 1; INFO: IND ADV: advise "CREATE INDEX CONCURRENTLY ON public.t USING btree (a)" NOTICE: IND ADV: old cost 0.00..170.00 NOTICE: IND ADV: new cost 0.04..2.25 NOTICE: IND ADV: saved cost -0.04..167.75 NOTICE: IND ADV: estimate 75.5 times faster QUERY PLAN --------------------------------------------------- Seq Scan on t (cost=0.00..170.00 rows=1 width=8) Filter: (a = 1) (2 rows)
根據比較條件推薦單列索引。
/*FORCE_SLAVE*/ explain select * from t where a > 10; -- 索引篩選不了多少數據因此沒有推薦索引 QUERY PLAN ------------------------------------------------------ Seq Scan on t (cost=0.00..170.00 rows=9990 width=8) Filter: (a > 10) (2 rows) /*FORCE_SLAVE*/ explain select * from t where a < 10; INFO: IND ADV: advise "CREATE INDEX CONCURRENTLY ON public.t USING btree (a)" NOTICE: IND ADV: old cost 0.00..170.00 NOTICE: IND ADV: new cost 0.04..2.39 NOTICE: IND ADV: saved cost -0.04..167.61 NOTICE: IND ADV: estimate 71.1 times faster QUERY PLAN --------------------------------------------------- Seq Scan on t (cost=0.00..170.00 rows=9 width=8) Filter: (a < 10) (2 rows)
根據多個等值或比較條件推薦組合索引。
/*FORCE_SLAVE*/ explain select * from t where a = 1 and b = 1; INFO: IND ADV: advise "CREATE INDEX CONCURRENTLY ON public.t USING btree (b, a)" NOTICE: IND ADV: old cost 0.00..195.00 NOTICE: IND ADV: new cost 0.04..1.16 NOTICE: IND ADV: saved cost -0.04..193.84 NOTICE: IND ADV: estimate 168.8 times faster QUERY PLAN --------------------------------------------------- Seq Scan on t (cost=0.00..195.00 rows=1 width=8) Filter: ((a = 1) AND (b = 1)) (2 rows)
根據
Order BY
算子推薦單列索引。/*FORCE_SLAVE*/ explain select * from t order by a limit 10; INFO: IND ADV: advise "CREATE INDEX CONCURRENTLY ON public.t USING btree (a)" NOTICE: IND ADV: old cost 361.10..361.12 NOTICE: IND ADV: new cost 0.04..0.26 NOTICE: IND ADV: saved cost 361.06..360.86 NOTICE: IND ADV: estimate 1366.8 times faster QUERY PLAN ------------------------------------------------------------------- Limit (cost=361.10..361.12 rows=10 width=8) -> Sort (cost=361.10..386.10 rows=10000 width=8) Sort Key: a -> Seq Scan on t (cost=0.00..145.00 rows=10000 width=8) (4 rows)
根據
Group BY
算子推薦單列索引。/*FORCE_SLAVE*/ explain select a,sum(b) from t group by a having a < 10 ; INFO: IND ADV: advise "CREATE INDEX CONCURRENTLY ON public.t USING btree (a)" NOTICE: IND ADV: old cost 170.14..170.30 NOTICE: IND ADV: new cost 0.04..2.53 NOTICE: IND ADV: saved cost 170.11..167.77 NOTICE: IND ADV: estimate 67.4 times faster QUERY PLAN --------------------------------------------------------------- GroupAggregate (cost=170.14..170.30 rows=9 width=12) Group Key: a -> Sort (cost=170.14..170.17 rows=9 width=8) Sort Key: a -> Seq Scan on t (cost=0.00..170.00 rows=9 width=8) Filter: (a < 10) (6 rows)
根據等值連接操作推薦單列索引。
/*FORCE_SLAVE*/ explain select * from t t1,t t2 where t1.a = t2.a limit 10; INFO: IND ADV: advise "CREATE INDEX CONCURRENTLY ON public.t USING btree (a)" NOTICE: IND ADV: old cost 270.00..270.28 NOTICE: IND ADV: new cost 0.07..0.70 NOTICE: IND ADV: saved cost 269.93..269.58 NOTICE: IND ADV: estimate 384.3 times faster QUERY PLAN ---------------------------------------------------------------------------- Limit (cost=270.00..270.28 rows=10 width=16) -> Hash Join (cost=270.00..552.50 rows=10000 width=16) Hash Cond: (t1.a = t2.a) -> Seq Scan on t t1 (cost=0.00..145.00 rows=10000 width=8) -> Hash (cost=145.00..145.00 rows=10000 width=8) -> Seq Scan on t t2 (cost=0.00..145.00 rows=10000 width=8) (6 rows)