螞蟻金服OceanBase挑戰TPCC | TPC-C基準測試之SQL優化

螞蟻金服自研數據庫 OceanBase 登頂 TPC-C 引發業內普遍關注,爲了更清楚的展現其中的技術細節,咱們特地邀請 OceanBase 核心研發人員對本次測試進行技術解讀,共包括五篇:數據庫

1)TPC-C基準測試介紹
2)OceanBase如何作TPC-C測試
3)TPC-C基準測試之SQL優化
4)TPC-C基準測試之數據庫事務引擎的挑戰
5)TPC-C基準測試之存儲優化編程

本文爲第二篇,其它文章已同步發佈,詳情請在「螞蟻金服科技」公衆號查看。segmentfault

TPC-C 是一個很是嚴苛的基準測試模型,考驗的是一個完備的關係數據庫系統全鏈路的能力。這也是爲何在 TPC-C 的榜單前列,出現的永遠只是你們熟知的那幾家在業界有着幾十年積累、從關係數據庫理論開始發展就差很少同步出現的數據庫公司。接下來咱們經過這篇文章爲您分析在 TPC-C 測試中 OceanBase 數據庫的 SQL 模塊具體遇到了哪些挑戰、作出了哪些優化。

背景

對 TPC-C 有所瞭解人都知道,TPC-C 是一個典型的 OLTP (On-Line Transaction Processing) 場景測試,考察的是數據庫在高併發壓力場景下的事務處理能力,最終的性能指標以 tpmC(transaction per minute,也即每分鐘系統處理 TPC-C 模型中的 new order 事務的數量)和平均到每 tpmC 的系統成本做爲衡量標準。在 OLTP 場景中,每條請求的響應時間都是極短的。所以,各個數據庫廠商在進行 TPC-C 測試時,都會盡一切可能將每個操做時間壓縮到最短,不誇張的說,在 TPC-C 的測試中,一些關鍵操做的優化每每須要細化到 CPU 指令級。緩存

在進入咱們的主題前,咱們先來談談 TPC-C 中的事務模型,主要分爲五種事務,訂單建立、訂單支付、訂單查詢、訂單發貨以及庫存查詢,這五種事務按照必定的比例發生,測試最終衡量的是每分鐘訂單建立事務的執行個數。你們知道,每個數據庫的事務,其實就是由必定邏輯關係關聯的若干條 SQL 語句組成,他們在一個事務中,要麼所有成功,要麼所有失敗,這個在數據庫中稱爲「原子性」,也就是 ACID 中的「A」。那麼 TPC-C 中的一個事務的耗時大約是多久呢?看一下報告就很清楚了——只有十幾個毫秒。考慮到一個事務由多條 SQL 構成,那麼每一條 SQL 的平均耗時都不到 1 毫秒!網絡

在 C/S(client-server)模型中,一條 SQL 語句從發起到執行完成須要經歷從客戶端輸入、網絡傳輸、SQL 優化、執行、結果返回到客戶端這樣一個流程。而具體每一條 SQL 的執行可能只是作一個字段的更新,所須要的執行時間是很是短暫的,從整個鏈路的角度來看,大量的時間會花費在與客戶端的交互過程當中,形成資源的浪費和耗時的增長。那麼如何解決這個問題的呢?答案就是使用存儲過程。數據結構

存儲過程

所謂「存儲過程」就是數據庫爲用戶提供的一種面向過程的編程語言。基於這種語言,用戶能夠將應用程序的邏輯封裝爲一個可調用的過程(procedure)存放在數據庫中並隨時進行調用。經過這種方式,用戶能夠將原本須要與數據庫進行屢次交互才能完成的工做經過一次交互完成,省去了中間網絡的傳輸和等待時間(參見圖1)。假如一條事務的網絡開銷平均是 30%,也就是說 30% 的 CPU 都花在了網絡的收發和解析上。那麼在 6 千萬規模 tpmC 測試中節省下來 30% 的 CPU 資源換算成系統處理能力是驚人的。使用存儲過程還能夠帶來事務響應時間的降低,致使數據庫內核中事務鎖的臨界區縮短,間接的提高了系統 CPU 利用率,整個吞吐量也隨之提升。存儲過程在縮短應用端的等待耗時上一樣有很大做用。併發

image.png
圖1 傳統的 C/S 模型與使用存儲過程的執行方式對比框架

在 TPC-C 中,存儲過程對於整個系統的執行效率提高是相當重要的。OceanBase 2.2 版本不只全面支持了存儲過程,並且對存儲過程的執行效率作了大量極致的優化。編程語言

編譯執行

存儲過程做爲一種面向過程的高級語言,須要轉換成機器碼纔可以執行。這個過程通常能夠分爲「編譯執行」和「解釋執行」兩種,通常來講,編譯執行相比解釋執行有代碼優化充分、執行效率高等特色。OceanBase 利用近兩年逐漸成熟的 LLVM 編譯器框架實現了一個支持存儲過程的編譯器,經過動態編譯(Just-in-Time Compilation)的方式將存儲過程翻譯成高效的二進制可執行代碼,在執行效率上得到了數量級的提高。同時,過程當中 LLVM 框架將存儲過程轉換爲與機器無關的中間代碼,使得存儲過程也天然而然地得到了跨平臺的編譯執行能力,LLVM 內置的優化過程確保咱們在各類不一樣的硬件平臺上均可以得到正確、高效的可執行代碼。分佈式

Array Binding

另一個在 TPC-C 測試中發揮了重要做用的功能就是對 DML 語句進行批量處理的能力,在 Oracle 中該功能也稱爲「Array Binding」。一條 SQL 在數據庫中的執行過程大體上能夠分爲「計劃生成」和「執行」兩個階段。儘管咱們對 SQL 的執行計劃作了高速緩存,但找到一個合適的執行計劃在整個執行過程當中仍然是比較耗時的一個部分。那有沒有辦法省去這個時間呢?當一組 SQL 的執行計劃徹底同樣而只有執行參數不一樣時,在存儲過程當中咱們能夠經過特定的語法將他們的執行作成一個批量處理的過程,此時「計劃生成」只須要作一次便可,這就是所謂的「Array Binding」。

在 Array Binding 中,數據庫會首先找到須要使用的計劃,而後執行該計劃,並在每次執行完畢後,從新執行參數綁定(binding)的過程。打個比方,這就像是在一個 C 語言的 for 循環中,反覆賦值而不是從新定義一個數據結構。Array Binding 的使用受用戶控制,須要在存儲過程當中使用 FORALL 關鍵字來觸發這一功能,在 TPC-C 的測試過程當中,咱們屢次使用了 Array Binding 來提高系統的處理能力,效果很是明顯。

Prepared Statement 與執行計劃緩存

Prepared Statement 是一種二進制的請求交互協議,能夠大大下降系統的交互成本。OceanBase 不只支持用戶程序與數據庫間使用 Prepared Statement, 也支持在存儲過程引擎調用 SQL 引擎執行時使用這種交互方式。存儲過程在對 SQL 進行一次 Prepare 操做並獲取惟一 id 後, 後續的每次執行僅須要傳入該 id 和對應的參數,系統能夠經過高速緩存找到對應的存儲過程或 SQL 計劃開始執行。該過程相比使用 SQL 文本的交互方式,省去了大量請求文本解析的 CPU 開銷。

OceanBase 內部實現了高速緩存來緩存存儲過程的可執行代碼及 SQL 執行計劃, 不一樣參數的存儲過程和 SQL 能夠經過這一高速緩存快速獲取須要的執行對象, 耗時通常在幾十微秒之內, 有效避免了從新編譯帶來的毫秒級的延遲和 CPU 消耗。

可更新視圖

在 OLTP 場景中,經過減小應用與數據庫的交互次數來實現性能提高的例子不少,可更新視圖就是其中之一。咱們常見的數據庫視圖一般是隻讀的,經過定義視圖,用戶能夠定義本身感興趣的數據以及其獲取接口,但視圖同時也能夠做爲更新操做的入口,好比在 TPC-C 的 new order 建立場景中,應用須要獲得商品信息,更新庫存並獲得更新後的值。通常能夠經過兩條 SQL 實現這一過程:

image.png

但經過創建一個可更新視圖:

image.png

咱們就能夠經過一條語句更新庫存並獲得商品和庫存信息:

image.png

這樣就省去了一條語句的交互,而且更新邏輯更加直觀。可更新視圖容許用戶能夠像普通表同樣操做視圖,但不是全部視圖均可以定義爲可更新視圖。好比帶 distinct, group by 的視圖,具體更新哪些行語義是不明確的,所以不能容許更新。具體到上面的 stock_item 兩表 join 的視圖,須要知足所更新表的 unique key 在 join 以後保持 unique (key-preserved table),即 item.i_id 必須是惟一的這個前提。

須要強調,TPC-C 規範禁止使用物化視圖,而可更新視圖並無改變底層數據表格的存儲形式,是符合規範的。

總結

由於 TPC-C 的設計原則是儘量的「真實」反應一個 OLTP 系統的運行場景,咱們所作的不少優化都具備普遍的適用性。例如,對於一個高併發的 OLTP 系統來講,大部分的 SQL 請求的耗時是很是短的,採用純粹的 C/S 交互模型的後果必然使系統的時間浪費在應用與數據庫的頻繁交互中,而使用存儲過程能夠大大緩解這種交互的耗時,而且加強系統對於網絡抖動的免疫力,這種核心能力對於一個分佈式 OLTP 數據庫是不可或缺的。

OceanBase 從創立伊始就堅持走自主研發的道路,這個選擇確保了咱們對數據庫內核有着徹底的掌控能力,讓咱們有在任何場景下追求極致性能的底氣和實力的同時,也對產品形態的發展方向有更清晰的規劃和目標。在此次的 TPC-C 測試中,咱們採用了 OceanBase 2.0 版本開始支持的 Oracle 兼容模式,存儲過程和 SQL 所有使用了兼容 Oracle 的數據類型和語法,這樣作也是爲了在追求極致優化的同時,確保產品迭代能夠沿着通用和正規的方向發展。從 OceanBase 2.0 版本開始,OceanBase 就不斷朝着 Oracle 兼容這個大的目標前進,隨着 2.2 版本支持的存儲過程(PL/SQL)功能的完善,咱們的產品功能也完成了一輪新的迭代。咱們堅信此次的 TPC-C 測試結果不只僅見證了 OceanBase 的極致性能,也將成爲 OceanBase 數據庫走向成熟產品的一個新起點。

做者介紹

陳萌萌,現任螞蟻金服 OceanBase 團隊資深技術專家,負責 OceanBase SQL 方向的研發工做。2006 年畢業於清華大學,2006 年到 2008 年在歐洲核子研究中心(CERN)負責網格計算調度器的開發工做,2009 年在美國威斯康星大學麥迪遜分校得到計算機碩士學位,前後在 Oracle、華爲美國研究所從事數據庫的開發和研究。

潘毅,現任螞蟻金服 OceanBase 團隊資深技術專家,負責 OceanBase 的並行查詢和新一代 OLAP 引擎。曾就任於美國 Oracle 公司,負責 Oracle 數據庫並行查詢研發工做並有多項專利申請。

相關文章
相關標籤/搜索