索引優(yōu)化通常需要依賴(lài)運(yùn)維或開(kāi)發(fā)人員對(duì)數(shù)據(jù)庫(kù)引擎內(nèi)部?jī)?yōu)化和執(zhí)行原理的深入理解。為優(yōu)化體驗(yàn)和降低操作門(mén)檻,PolarDB-X 1.0推出了基于代價(jià)優(yōu)化器的索引推薦功能,可根據(jù)查詢(xún)語(yǔ)句分析并推薦索引,幫助您降低查詢(xún)耗時(shí),提升數(shù)據(jù)庫(kù)性能。

注意事項(xiàng)

索引推薦功能僅針對(duì)您當(dāng)前指定的SQL查詢(xún)語(yǔ)句進(jìn)行分析與推薦。在根據(jù)推薦的信息創(chuàng)建索引前,您需要評(píng)估創(chuàng)建該索引對(duì)其它查詢(xún)的影響。

環(huán)境說(shuō)明

TPC-H是業(yè)界常用的基準(zhǔn)測(cè)試方法,由TPC委員會(huì)制定發(fā)布,用于評(píng)測(cè)數(shù)據(jù)庫(kù)的分析型查詢(xún)能力。TPC-H基準(zhǔn)測(cè)試方法包含8張數(shù)據(jù)表、22條復(fù)雜的SQL查詢(xún)(即Q1~Q22)。下圖為執(zhí)行TPC-H中的Q17(小訂單收入查詢(xún))的返回信息,可查看到執(zhí)行該查詢(xún)語(yǔ)句消耗的時(shí)間為28.76秒。本文將通過(guò)智能索引推薦功能,優(yōu)化該查詢(xún)語(yǔ)句的執(zhí)行效率。

說(shuō)明 關(guān)于TCP-H中查詢(xún)語(yǔ)句的詳細(xì)介紹,請(qǐng)參見(jiàn)TPC-H的SQL語(yǔ)句分析。

本文的TPC-H的實(shí)現(xiàn)基于TPC-H的基準(zhǔn)測(cè)試,并不能與已發(fā)布的TPC-H基準(zhǔn)測(cè)試結(jié)果相比較,本文中的測(cè)試并不符合TPC-H基準(zhǔn)測(cè)試的所有要求。

圖 1. 智能索引優(yōu)化前
智能索引優(yōu)化前

步驟一:查詢(xún)智能索引推薦信息

如需查詢(xún)某個(gè)查詢(xún)語(yǔ)句的智能索引推薦信息,您只需在該查詢(xún)語(yǔ)句前增加EXPLAIN ADVISOR命令,示例如下:

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);

執(zhí)行上述命令后,PolarDB-X 1.0將返回推薦的索引創(chuàng)建語(yǔ)句、添加索引前后的代價(jià)等信息,詳細(xì)的返回信息及其注釋如下所示:

說(shuō)明
  • 本案例中,預(yù)計(jì)磁盤(pán)I/O提升百分比為3024.7%,表明使用推薦的索引將帶來(lái)較大的收益。
  • 當(dāng)PolarDB-X 1.0無(wú)法推薦索引時(shí),返回信息中會(huì)建議您在業(yè)務(wù)低峰期,對(duì)目標(biāo)表執(zhí)行Analyze Table命令刷新統(tǒng)計(jì)信息(該操作會(huì)消耗較大的I/O資源)。當(dāng)統(tǒng)計(jì)信息更新后,再次執(zhí)行索引推薦可獲得更準(zhǔn)確的索引。
IMPROVE_VALUE: 2465.3%        # 預(yù)計(jì)綜合代價(jià)提升百分比
  IMPROVE_CPU: 59377.4%       # 預(yù)計(jì)CPU提升百分比
  IMPROVE_MEM: 0.4%           # 預(yù)計(jì)內(nèi)存提升百分比
   IMPROVE_IO: 3024.7%        # 預(yù)計(jì)磁盤(pán)I/O提升百分比
  IMPROVE_NET: 2011.1%        # 預(yù)計(jì)網(wǎng)絡(luò)傳輸提升百分比
 BEFORE_VALUE: 4.711359845E8  # 添加索引前綜合代價(jià)值
   BEFORE_CPU: 1.19405577E7   # 添加索引前CPU估算值
   BEFORE_MEM: 426811.2       # 添加索引前內(nèi)存消耗估算值
    BEFORE_IO: 44339          # 添加索引前磁盤(pán)I/O估算值
   BEFORE_NET: 47.5           # 添加索引前網(wǎng)絡(luò)傳輸估算值
  AFTER_VALUE: 1.83655008E7   # 添加索引后綜合代價(jià)值
    AFTER_CPU: 20075.8        # 添加索引后CPU估算值
    AFTER_MEM: 425016         # 添加索引后內(nèi)存消耗估算值
     AFTER_IO: 1419           # 添加索引后磁盤(pán)I/O估算值
    AFTER_NET: 2.2            # 添加索引后網(wǎng)絡(luò)傳輸估算值
 ADVISE_INDEX: ALTER TABLE `lineitem` ADD  INDEX `__advise_index_lineiteml_partkey`(`l_partkey`);
/* ADVISE_INDEX中的內(nèi)容為推薦的索引創(chuàng)建語(yǔ)句 */
     NEW_PLAN:                # 添加索引后預(yù)計(jì)執(zhí)行計(jì)劃
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    # 其它信息

步驟二:根據(jù)推薦信息創(chuàng)建索引

  1. 評(píng)估創(chuàng)建該索引帶來(lái)的收益,然后根據(jù)返回結(jié)果ADVISE_INDEX中的SQL語(yǔ)句創(chuàng)建索引。
    ALTER TABLE `lineitem` ADD  INDEX `__advise_index_lineiteml_partkey`(`l_partkey`);
  2. 再次執(zhí)行TPC-H中的Q17(小訂單收入查詢(xún)),耗時(shí)減少至1.41秒,查詢(xún)效率得到大幅提升。
    圖 2. 智能索引優(yōu)化后
    智能索引優(yōu)化后