ClickHouse為什麼查詢速度快?

danny_2018發表於2023-01-11

導讀:ClickHouse速度快的秘訣在於——利用儲存引擎的特殊設計充分減少磁碟I/O對查詢速度的影響。

ClickHouse為什麼查詢速度快?本文來揭秘。

01

從儲存引擎視角看

ClickHouse速度快的秘訣在於——利用儲存引擎的特殊設計充分減少磁碟I/O對查詢速度的影響。從使用者提交一條SQL語句進行查詢到最終輸出結果的過程中,大量的時間是消耗在了磁碟I/O上,在很多情況下,I/O所佔用的時間可以達到整個時間的90%以上。對儲存引擎磁碟I/O的最佳化可以獲得非常大的收益。ClickHouse的儲存引擎設計中大量最佳化的目的也是為了減少磁碟I/O。本節將從該視角對ClickHouse儲存引擎的最佳化進行解讀。

1、預排序

ClickHouse與傳統事務資料庫的一個不同之處在於ClickHouse寫入資料檔案的資料時有序的,這就是本節將要介紹的預排序:將資料在寫入磁碟前進行排序,以保證資料在磁碟上有序。

預排序在資料庫系統是一個被廣泛使用的技術,在實現範圍查詢時,可以將大量的隨機讀轉換為順序讀,從而有效提高I/O效率,降低範圍查詢時的I/O時間。在點查詢時,預排序能做到和未排序資料相同的效能。因此,預排序可以在不降低點查詢效能的情況下,有效提高範圍查詢的效能。

2、列存

列存資料庫和行存資料庫最根本的區別在於列存資料庫將一行資料拆分到多個資料檔案中。在列存資料庫中,同一列的所有資料都在同一個檔案中,因此在硬碟上是連續的。這種特性特別適合OLAP的低正規化查詢場景。

3、壓縮

ClickHouse的另一個降低I/O的手段是壓縮,壓縮可以減少讀取和寫入的資料量,從而減少I/O時間。並不是所有場景下都可以引入壓縮的,很顯然,壓縮必然帶來壓縮和解壓縮的CPU消耗,這是一個利用CPU時間換I/O時間的手段。事務資料庫由於大部分情況下是針對行的操作,因此如果對每一行都進行一次壓縮解壓縮,帶來的時間消耗是遠大於磁碟I/O時間的。這就是事務資料庫沒有使用壓縮技術的原因。

而ClickHouse則不同,ClickHouse的最小處理單元是塊,塊一般由8192行資料組成,ClickHouse的一次壓縮針對的是8192行資料,這就極大降低CPU的壓縮和解壓縮時間。同時,ClickHouse是列存資料庫,同一列的資料相對更有規律,因此能夠帶來比較大的壓縮比。因此,塊+壓縮在ClickHouse中成為一個非常關鍵的最佳化手段。

02

從計算引擎視角看

不同於儲存引擎的設計,ClickHouse計算引擎的設計在很多方面都有著很大的爭議,一方面向量化引擎的精妙設計讓人拍案叫絕,另一方面相對粗糙的SQL解析和最佳化(解釋)器也讓ClickHouse在執行某些操作時讓使用者咬牙切齒。

1、 ClickHouse速度快的前提

在正式進入本節內容之前,我們首先需要明確一個前提:ClickHous不是在所有場景下都能獲得很強的效能。因此,需要先分析ClickHouse在滿足哪些前提下才能獲得最強的查詢效能。

ClickHouse計算引擎最精妙的設計在於向量化引擎,那麼ClickHouse由於計算引擎原因導致的快,肯定是來自向量化引擎的加持。而ClickHouse的計算引擎導致的慢是因為缺乏代價最佳化器,那麼由於計算引擎導致的慢也來自缺乏代價最佳化器帶來的缺陷。基於這兩個邏輯,我們可以分析出ClickHouse速度快的前提。

1)大量使用向量化運算

ClickHouse提供了很多內建函式,在使用這些內建函式時,ClickHouse會自動進行向量化最佳化。因此儘可能使用提供的內建函式進行計算,而不是自己寫SQL語句。

2)查詢語句中沒有使用Join子句,或儘可能少的使用Join操作

ClickHouse沒有代價最佳化器,這導致了ClickHouse在Join操作時會出現記憶體不足等情況,導致查詢失敗。Join的效能問題其實並不僅僅是ClickHouse才遇到,任何資料庫在遇到大表Join時都有可能導致查詢時間暴增。

大資料中的Spark計算引擎對Join操作做了非常多的最佳化,藉助其強大的CBO實現了Join演算法的自動選擇。更是在此基礎上,透過AQE(Adaptive Query Execution,自適應查詢引擎),解決了大表Join操作時遇到資料傾斜時的效能問題。

正是由於ClickHouse沒有實現CBO,因此ClickHouse在實現Join操作時,選擇餘地很少。尤其是分散式大表Join操作時,ClickHouse只實現了廣播連線(Broadcast Join)演算法,極大地降低了ClickHouse的Join能力。

在使用ClickHouse時,應當儘可能避免Join操作。而Join操作在ODS建模的過程中大量存在。因此,ClickHouse在設計良好的DW上執行向量化查詢的效能最高。讀者應該儘可能避免將ClickHouse用於ODS的建模工作中。當資料量大時,這類建模工作還是儘可能下推到Spark上執行。

2、ClickHouse快的本質

ClickHouse在滿足上面提到的兩個條件時,在不考慮儲存引擎影響的情況下,應當能夠在計算引擎上達到最大的效能。ClickHouse計算引擎快的本質是利用了CPU提供的硬體加速特性。

除此之外,ClickHouse客觀上的確在一些環節存在著一些問題,個人認為這些問題和ClickHouse的定位有關。ClickHouse在設計之初就給自身進行了清晰的定位——充分發揮單機效能的OLAP引擎。在此基礎上,分散式的join能力其實並不重要,畢竟業界已經有Spark了,完全可以將ClickHouse建立在Spark之上,由Spark解決建模問題,由ClickHouse強大的DW分析能力實現OLAP的最後一公里問題。

作為使用者,我們應該清晰地瞭解ClickHouse速度快的前提,有意識地避開ClickHouse的雷區,不要將ClickHouse用於其不擅長的場景。正如此時此刻,大家都意識到了MySQL無法解決大資料量的OLAP問題,這類問題要透過專業的OLAP引擎解決。

開源社群要的並不是什麼能力都有的但都不強的平庸的軟體,而是百花齊放,各自有著各自擅長的領域,透過組合實現架構上的合力。以上僅代表作者個人觀點,歡迎讀者有不同意見,大家互相討論。

03

總結

本文分別對ClickHouse的儲存引擎和計算引擎進行了簡單分析,分別得出了ClickHouse速度快的不同的前提。

儲存引擎需求的前提如下。

使用MergeTree儲存引擎。

按照業務需求,正確設定資料表的排序鍵,查詢時需滿足最左原則。

計算引擎架構要求的前提如下。

沒有或少用Join操作。

儘可能多地使用內建函式。

當滿足如上4個條件時,使用ClickHouse才有可能達到比較優秀的效能。

來自 “ 數倉寶貝庫 ”, 原文作者:陳峰;原文連結:https://mp.weixin.qq.com/s/WnD-oYx8Ab-fxsvJan_Kww,如有侵權,請聯絡管理員刪除。

相關文章