本文介紹數據庫自治服務DAS(Database Autonomy Service)的Cost-based SQL診斷引擎。

背景信息

在業務系統中,數據庫扮演著舉足輕重的角色。和其它公司一樣,在阿里巴巴業務場景下,大部分業務跟數據庫有著非常緊密的關系,數據庫一個微小的抖動都有可能對業務造成非常大的影響,如何讓數據庫更穩定,得到持續優化一直都是非常重要的訴求。數據庫環境下的業務優化,通常涉及三個層面:
  • 應用層面優化:應用代碼邏輯優化,以更高效的方式處理數據。
  • 實例層面優化:通過環境參數調整,優化實例的運行效率。
  • SQL層面優化:通過物理數據庫設計、SQL語句改寫等優化手段,確保以最佳的方式獲取數據。

開發者通常對于前面兩個層面的優化比較熟悉,對于第三個即SQL層面的優化會有些生疏,甚至會因由誰(數據庫管理員或應用開發者)來負責而產生爭論,但SQL優化是整個數據庫優化中非常關鍵的一環,線上SQL性能問題不僅會給業務帶來執行效率上的低下,甚至是穩定性上的故障。

按照經驗,約80%的數據庫性能問題能通過SQL優化手段解決,但SQL優化一直以來都是一個非常復雜的過程,需要多方面的數據庫領域專家知識和經驗。

例如如何準確地識別執行計劃中的瓶頸點,通過優化物理庫設計或SQL改寫等手段,讓數據庫優化器執行最佳計劃。另外,由于SQL工作負載及其基礎數據龐大且不斷變化,SQL優化還是一項非常耗時且繁重的任務,這些都決定了SQL優化是一項高門檻、高投入的工作。

面臨挑戰

當我們提到診斷優化能力時,很自然會想到兩個問題:
  • 能力是否靠譜?
  • 能力是否全面?
解決這兩個問題將面臨非常巨大的挑戰,可以將其歸納為如下四點:
  • 如何選擇靠譜的優化推薦算法生成靠譜的建議?
    在SQL診斷優化領域,基于規則和基于代價模型是兩種常被選擇的優化推薦算法。
    • 基于規則
      在目前許多產品和服務中,基于規則的推薦方式被廣泛使用,特別是針對MySQL這種WHAT-IF內核能力缺失的數據庫,因為該方式相對來說比較簡單,容易實現,但另一面也造成了推薦過于機械化,推薦質量難以保證的問題,例如對如下簡單SQL進行索引推薦:
      SELECT *
      FROM t1
      WHERE time_created >= '2017-11-25'
      AND consuming_time > 1000
      ORDER BY consuming_time DESC;
      基于規則,通常會首先生成如下四個候選索引:
      IX1(time_created)
      IX2(time_created, consuming_time)
      IX3(consuming_time)
      IX4(consuming_time, time_created)

      但最終推薦給用戶的是哪個(或哪幾個,考慮index oring/anding的情況)索引呢?基于規則的方式很難給出精確的回答,會出現模棱兩可的局面。在這個例子中,SQL只是簡單的單表查詢,那對于再復雜一點的SQL,例如多個表Join,以及帶有復雜的子查詢,情況又會如何呢?情況變得更糟糕,更加難以為繼。

    • 基于代價模型
      與基于規則不同,DAS中的SQL診斷優化服務采用的是基于代價模型方式實現,即采用和數據庫優化器相同的方式去思考優化問題,最終會以執行代價的方式量化評估所有的(或盡可能所有的,因為是最優解求解的NP類問題,因此在一些極端情況下無法做到所有,只是實現次優)可能推薦候選項,最終作出推薦。即便是如此,但對于MySQL這樣的開源數據庫支持,還將面臨其它不一樣的挑戰:
      • WHAT-IF內核能力缺失:無法復用內核的數據庫優化器能力來對候選優化方案進行代價量化評估。
      • 統計信息缺失:候選優化方案的代價評估,其本質是執行計劃的代價計算,統計信息的缺失便是無米之炊。
  • 如何具備足夠的SQL兼容性?

    SQL診斷優化服務如何做到SQL兼容性,其中包括SQL的解析以及SQL語義的驗證,這直接關系到能力的全面性和診斷的成功率,它就像入場券,做不到做不全面都是問題。

  • 如何構建具有足夠覆蓋度的能力測試集?

    長期以來,SQL診斷優化能力的構建一直都是頗具挑戰性的課題,挑戰不僅在于如何融入數據庫優化領域專家知識,還包括如何構建一個龐大的測試案例庫用于其核心能力驗證,它就像一把尺子可以衡量能力,同時又可以以此為驅動,加速能力的構建,因此在整個過程中,擁有足夠覆蓋度,準確的測試案例庫是能力構建過程中至關重要的一環。

    但構建足夠好的測試案例庫是一件非常困難的事情,挑戰主要體現在兩個方面:
    • 足夠完備性保證:影響SQL優化的因素很多,例如影響索引選擇的因素有上百個,加之各因素之間形成組合,這就形成了龐大的案例特征集合,如何讓這些特征一一映射到測試案例也是非常龐大的工程。
    • 測試案例設計需要專業知識且信息量大,例如對于單一測試案例設計也需要專業知識且測試案例中攜帶的信息量大,如索引推薦測試案例,它包括:
      • schema設計:如表、已有索引、約束等。
      • 各類統計信息數據。
      • 環境參數等等。
  • 如何構建大規模的診斷服務能力?

    SQL診斷優化服務需要具備服務于云上百萬級數據庫實例的能力,其線上服務能力同樣面臨巨大挑戰,例如如何實現復雜的計算服務化拆分,計算服務的橫向伸縮,最大化的并行,資源訪問分布式環境下的并發控制,不同優先級的有效調度消除隔離,峰值緩沖等等。

解決方案

SQL診斷優化服務是阿里云數據庫自治服務DAS中最為核心的服務之一,它以SQL語句作為輸入,由DAS完成診斷分析并提供專家優化建議(包括索引建議、語句優化建議以及預期收益等信息),用戶不必精通數據庫優化領域專家知識,即可獲得SQL優化診斷、改寫和優化相關的專家建議,最大化SQL執行性能。

另外,依托該能力,DAS的SQL自動優化服務將SQL優化推向了更高的境界,將重人工的被動式優化轉變為以智能化為基礎的主動式優化,以自優化的自治能力實現SQL優化的無人值守。

能力構建

面對上面提到的眾多挑戰,本文著重從DAS中的SQL診斷優化引擎核心技術架構以及能力測試集的構建兩個維度進一步解讀。

SQL診斷優化引擎核心架構
上圖是SQL診斷優化引擎的核心架構,它實現一套獨立于數據庫之外的優化器,包括自適應的統計信息收集以及執行計劃的代價計算,以此為基礎彌補WHAT-IF內核能力缺失,自適應的統計信息收集彌補統計信息缺失。其具體的工作過程如下:
  1. SQL解析與驗證:引擎對查詢語句做解析驗證,驗證輸入查詢語句是否符合標準,識別查詢語句的組成形成語法樹,例如:謂詞以及謂詞類型、排序字段、聚合字段、查詢字段等,識別查詢語句相關字段的數據類型。驗證SQL使用到的表、字段是否符合目標數據庫的結構設計。
  2. 候選索引生成:依據解析驗證后的語法樹,生成多種候選索引組合。
  3. 基于代價評估:代價評估基于內置獨立于數據庫內核的優化器,獲取數據庫統計信息,在診斷引擎內部作緩存。診斷引擎內置優化器基于統計信息計算代價,評估每個索引的代價以及不同SQL改寫方法下的代價評估,從而從代價選擇最優索引或SQL改寫方法。
  4. 索引合并與擇優:引擎輸入可以是一條查詢語句,也可以為多個查詢語句,或者整個數據庫實例所有的查詢語句。為多個查詢語句做索引推薦,不同的查詢語句的索引建議,以及已經存在的物理索引,有可能存在相同索引、前綴相同索引、雷同索引。

構建具有足夠覆蓋度的能力測試集,并以此為尺,度量能力,驅動能力構建。在這一過程中,如下圖所示,DAS構建了以用例系統為中心的開發模式。

案例系統

能力測試集構建的基本思想,首先通過特征化實現測試案例基于特征的形式化描述,形成測試案例形式化特征庫,并具備足夠的完備性。

在阿里巴巴集團內部,我們已經對數據庫實例上全部SQL進行實時采集和存儲,借助阿里巴巴這個大平臺業務的豐富性和SQL場景的豐富性,以特征化形式描述為抓手對線上海量全量SQL資源分析搜尋符合指定特征的真實案例,抽取測試案例所需的信息,最終完成測試案例庫構建。
說明 案例庫的數據均來自阿里巴巴集團內部業務,所涉及的線上抽取信息,如統計信息,均經過加密脫敏處理,此過程為無人參與的全自動化過程。
最后通過“測試用例形式化特征庫”和“測試案例庫”的特征比對,可實現測試完備度和覆蓋度的評估,例如:
  • 哪些測形式化特征測試用例已被測試用例覆蓋,完備度是多少?
  • 哪些形式化特征測試用例,當前的診斷優化能力未覆蓋?或測試驗證失???
  • 在一段時間哪些測形式化特征測試用例出現頻繁的回歸問題?
  • 各能力級的測試用例覆蓋率怎樣?

優化

DAS的SQL診斷優化服務云上發布前,已在阿里巴巴集團內部穩定運行多年,日平均診斷量在5萬左右,很好地支撐著整個集團業務應用的SQL優化,使用場景應用場景主要包括:
  • 自助優化:集團用戶指定問題SQL,服務完成診斷并提供優化專家建議。
  • 自動優化:自動優化服務自動識別業務數據庫實例工作負載上的慢查詢,主動完成診斷,生成優化建議,評估后編排優化任務,自動完成后續的優化上線操作及性能跟蹤,形成全自動的優化閉環,提升數據庫性能,持續保持數據庫實例運行在最佳優化狀態。

更為重要的是,SQL診斷優化服務已經構建了有效的主動式分析,反饋系統,線上診斷失敗案例,用戶反饋案例,自動優化中的回滾案例會自動回流到案例系統,一刻不停地驅動著診斷服務在快速迭代中成長。

支持的引擎

SQL診斷目前已支持的數據庫引擎包括RDS MySQLPolarDB MySQL版、RDS PostgreSQLPolarDB PostgreSQL版(兼容Oracle)。

說明 對于PolarDB MySQL版數據庫引擎,支持列存索引推薦能力,為您推薦最優的列存索引,詳情請參見列存索引。