索引優化通常需要依賴運維或開發人員對數據庫引擎內部優化和執行原理的深入理解。為優化體驗和降低操作門檻,PolarDB-X推出了基于代價優化器的索引推薦功能,可根據查詢語句分析并推薦索引,幫助您降低查詢耗時,提升數據庫性能。
注意事項
索引推薦功能僅針對您當前指定的SQL查詢語句進行分析與推薦。在根據推薦的信息創建索引前,您需要評估創建該索引對其它查詢的影響。
環境說明
TPC-H是業界常用的基準測試方法,由TPC委員會制定發布,用于評測數據庫的分析型查詢能力。TPC-H基準測試方法包含8張數據表、22條復雜的SQL查詢(即Q1~Q22)。下圖為執行TPC-H中的Q17(小訂單收入查詢)的返回信息,可查看到執行該查詢語句消耗的時間為28.76秒。本文將通過智能索引推薦功能,優化該查詢語句的執行效率。
- 查詢智能索引推薦如需查詢某個查詢語句的智能索引推薦信息,您只需在該查詢語句前增加
EXPLAIN ADVISOR
命令即可,示例如下:
執行上述命令后,PolarDB-X將返回推薦的索引創建語句、添加索引前后的代價等信息,詳細的返回信息及其注釋:EXPLAIN ADVISOR SELECT sum(l_extendedprice) / 7.0 AS avg_yearly FROM lineitem, part WHERE p_partkey = l_partkey AND p_brand = 'Brand#23' AND p_container = 'MED BOX' AND l_quantity < (SELECT 0.2 * avg(`l_quantity`) FROM lineitem WHERE l_partkey = p_partkey);
- 本案例中預計磁盤I/O提升百分比為3024.7%,表明使用推薦的索引將帶來較大的收益。
- 當PolarDB-X無法推薦索引時,返回信息中會建議您在業務低峰期,對目標表執行
Analyze Table
命令刷新統計信息(該操作會消耗較大的I/O資源)。當統計信息更新后,再次執行索引推薦可獲得更準確的索引。IMPROVE_VALUE: 2465.3% # 預計綜合性能提升百分比 IMPROVE_CPU: 59377.4% # 預計CPU提升百分比 IMPROVE_MEM: 0.4% # 預計內存提升百分比 IMPROVE_IO: 3024.7% # 預計磁盤I/O提升百分比 IMPROVE_NET: 2011.1% # 預計網絡傳輸提升百分比 BEFORE_VALUE: 4.711359845E8 # 添加索引前綜合代價值 BEFORE_CPU: 1.19405577E7 # 添加索引前CPU估算值 BEFORE_MEM: 426811.2 # 添加索引前內存消耗估算值 BEFORE_IO: 44339 # 添加索引前磁盤I/O估算值 BEFORE_NET: 47.5 # 添加索引前網絡傳輸估算值 AFTER_VALUE: 1.83655008E7 # 添加索引后綜合代價值 AFTER_CPU: 20075.8 # 添加索引后CPU估算值 AFTER_MEM: 425016 # 添加索引后內存消耗估算值 AFTER_IO: 1419 # 添加索引后磁盤I/O估算值 AFTER_NET: 2.2 # 添加索引后網絡傳輸估算值 ADVISE_INDEX: ALTER TABLE `lineitem` ADD INDEX `__advise_index_lineiteml_partkey`(`l_partkey`); /* ADVISE_INDEX中的內容為推薦的索引創建語句 */ NEW_PLAN: # 添加索引后預計執行計劃 Project(avg_yearly="$f0 / ?0") HashAgg($f0="SUM(l_extendedprice)") Filter(condition="l_quantity < $16 * f17w0$o0") SortWindow(p_partkey="p_partkey", l_partkey="l_partkey", l_quantity="l_quantity", l_extendedprice="l_extendedprice", $16="$16", f5w0$o0="window#0AVG($2)", Reference Windows="window#0=window(partition {1} order by [] range between UNBOUNDED PRECEDING and UNBOUNDED PRECEDING aggs [AVG($2)])") MemSort(sort="l_partkey ASC") BKAJoin(condition="l_partkey = p_partkey", type="inner") Gather(concurrent=true) LogicalView(tables="[0000,0001].part", shardCount=2, sql="SELECT `p_partkey` FROM `part` AS `part` WHERE ((`p_brand` = ?) AND (`p_container` = ?))") Gather(concurrent=true) LogicalView(tables="[0000,0001].lineitem", shardCount=2, sql="SELECT `l_partkey`, `l_quantity`, `l_extendedprice`, ? AS `$16` FROM `lineitem` AS `lineitem` WHERE (`l_partkey` IN (...))") INFO: LOCAL_INDEX # 其它信息
- 根據推薦信息創建索引
- 評估創建該索引帶來的收益,根據返回結果
ADVISE_INDEX
中的SQL語句創建索引。ALTER TABLE `lineitem` ADD INDEX `__advise_index_lineiteml_partkey`(`l_partkey`);
- 再次執行TPC-H中的Q17(小訂單收入查詢),耗時減少至1.41秒,查詢效率得到大幅提升。
- 評估創建該索引帶來的收益,根據返回結果