GreatSQL重磅特性,InnoDB並行並行查詢優化測試

本文首發於 GreatSQL社區 微信公衆號。



GreatSQL馬上正式開源了,這次又新增了兩個重磅特性:InnoDB事務鎖優化 以及 InnoDB引擎的並行查詢優化,這兩個特性是由華爲鯤鵬計算團隊貢獻的Patch合併而來。

InnoDB並行查詢優化怎麼實現的?

根據B+樹的特點,可以將B+樹劃分爲若干子樹,此時多個線程可以並行掃描同一張InnoDB表的不同部分。對執行計劃進行多線程改造,每個子線程執行計劃與MySQL原始執行計劃一致,但每個子線程只需掃描表的部分數據,子線程掃描完成後再進行結果彙總。通過多線程改造,可以充分利用多核資源,提升查詢性能。

優化後,在TPC-H測試中表現優異,最高可提升30倍,平均提升15倍。

該特性適用於週期性數據彙總報表之類的SAP、財務統計等業務,例如月初、月底跑批業務等。

使用限制:

  • 暫不支持子查詢,可想辦法改造成JOIN。
  • 暫時只支持ARM架構平臺,X86架構平臺優化也會盡快完成。

關於該Patch詳情見:https://support.huaweicloud.com/fg-kunpengdbs/kunpengdbs_20_0005.html

本文針對 InnoDB引擎的並行查詢優化 特性進行對比測試。

1、測試環境

服務器:神州鯤泰R222,華爲Hi1616 * 2(主頻 2400 MHz 共64個邏輯CPU),256G內存。

操作系統:Docker 20.10.2,Docker容器下的CentOS Linux release 7.9.2009,Linux 4.15.0-29-generic。

本次測試採用TPC-H,dbgen構造測試數據參數 dbgen -vf -s 50,導入後數據庫物理大小約70G。GreatSQL關鍵配置:

#運行Q10測試時,需要較大臨時表
temptable_max_ram = 6G

#使得本測試基於純內存場景
innodb_buffer_pool_size=96G

#InnoDB並行查詢優化
#global級別,設置並行查詢的開關,bool值,on/off。默認off,關閉並行查詢特性。可在線動態修改。
force_parallel_execute = ON

#global級別,設置系統中總的並行查詢線程數。有效值的範圍是(0, ULONG_MAX),默認值是64。
parallel_max_threads = 64

#global級別,並行執行時leader線程和worker線程使用的總內存大小上限。有效值的範圍是(0, ULONG_MAX),默認值是1G
parallel_memory_limit = 32G

2、測試數據

測試過程中,注意要確保每次查詢都是基於純內存的場景,也就是確保innodb_buffer_pool_size大於數據庫物理大小,並確認查詢過程中沒有額外的物理I/O發生。

個別SQL例如Q10在運行過程中會產生臨時表(Using temporary),這時候需要加大 temptable_max_ram 選項值。該選項默認值1G,在上述測試數據量前提下,大概需要加大到4G才能hold住。如果該選項值不夠的話,可能運行過程中會提示諸如 The table '/tmp/#sql57_a1_0' is full 這樣的錯誤提示,然後退出查詢,這是MySQL的BUG#99100。

InnoDB並行查詢特性通過HINT語法可以很方便地使用,首先確認啓用了該特性(可在線動態打開):

$ mysqladmin var|grep force_parallel_execute
| force_parallel_execute                                   | ON

那麼默認所有的SQL只要符合條件,即可自動採用並行查詢,通過查看執行計劃確認:

mysql> EXPLAIN SELECT ... FROM ... WHERE ...
...
Parallel execute (4 workers)
...

可以看到執行計劃輸出中包含 Parallel execute (4 workers) 關鍵字,這就表示最高可並行4個線程查詢。

也可以查看樹狀執行計劃:

mysql> EXPLAIN FORMAT=TREE SELECT ... FROM ... WHERE ...
...
| -> Limit: 1 row(s)
    -> Sort: lineitem.l_returnflag, lineitem.l_linestatus, limit input to 1 row(s) per chunk
        -> Table scan on <temporary>
            -> Aggregate using temporary table
                -> Parallel scan on <temporary>
                    -> Sort: lineitem.l_returnflag, lineitem.l_linestatus
                        -> Table scan on <temporary>
                            -> Aggregate using temporary table
                                -> Filter: (lineitem.l_shipdate <= <cache>((DATE'1998-12-01' - interval '88' day)))  (cost=6342898.28 rows=19669815)
                                    -> PQblock scan on lineitem  (cost=6342898.28 rows=59015354)
...

可以看到執行計劃中包含 PQblock scan on ... 關鍵字,並且注意到同一行裏提示 cost=6342898.28,這是啓用並行查詢的條件之一,也就是 cost 超過了 parallel_cost_threshold = 1000 設置的閾值開關。

一條SQL若不想啓用並行查詢,加上相應的HINT即可:

mysql> SELECT /*+ NO_PQ */ ... FROM ... WHERE ...

也可以動態調整並行線程數爲最高64線程:

mysql> SELECT /*+ PQ(64) */ ... FROM ... WHERE ...

好了,直接查看結果對比數據:

TPCH 並行掃描(默認參數)
耗時(秒)
並行掃描(參數優化後)
耗時(秒)
未優化前
耗時(秒)
並行掃描 vs 未優化前的提升 提高查詢並行讀優化後提升
Q1 616.407015 43.688772 1396.791060 31.971 14.109
Q3 139.579648 24.343778 330.946837 13.595 5.734
Q5 343.604734 30.501792 338.576433 11.100 11.265
Q6 248.830780 20.128220 233.490352 11.600 12.362
Q10 155.077042 41.948881 263.921069 6.291 3.697
Q12 325.281718 24.850585 582.405888 23.436 13.089
Q19 17.475904 5.296522 42.447522 8.014 3.300

從這個測試結果簡單概括幾條:

  • 1、 平均提升約14倍,最高提升約32倍
  • 2、如果併發量更高,則優化效果更好。
  • 3、Q5原始SQL性能提升不多,調整JOIN順序後性能提升顯著(從只提升28%躍升到11倍)。

GreatSQL將於近期正式開源,歡迎關注。

全文完。

Enjoy GreatSQL :)


文章推薦:



掃碼加入GreatSQL/MGR交流QQ羣



點擊文末“閱讀原文”直達老葉專欄

本文分享自微信公衆號 - 老葉茶館(iMySQL_WX)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章