ClickHouse是一個用於聯機分析(OLAP)的列式數據庫管理系統(DBMS);目前咱們使用CH做爲實時數倉用於統計分析,在作性能優化的時候使用了 物化視圖
這一特性做爲優化手段,本文主要分享物化視圖的特性與如何使用它來優化ClickHouse的查詢性能。sql
數據庫中的 視圖(View)
指的是經過一張或多張表查詢出來的 邏輯表 ,自己只是一段 SQL 的封裝並 不存儲數據。數據庫
而 物化視圖(Materialized View)
與普通視圖不一樣的地方在於它是一個查詢結果的數據庫對象(持久化存儲),很是趨近於表;物化視圖是數據庫中的預計算邏輯+顯式緩存,典型的空間換時間思路,因此用得好的話,它能夠避免對基礎表的頻繁查詢並複用結果,從而顯著提高查詢的性能。緩存
在傳統關係型數據庫中,Oracle、PostgreSQL、SQL Server等都支持物化視圖,而做爲MPP數據庫的ClickHouse也支持該特性。性能優化
ClickHouse中的物化視圖能夠掛接在任意引擎的基礎表上,並且會自動更新數據,它能夠藉助 MergeTree 家族引擎(SummingMergeTree、Aggregatingmergetree等),獲得一個實時的預聚合,知足快速查詢;可是對 更新 與 刪除 操做支持並很差,更像是個插入觸發器。架構
建立語法:性能
CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...
POPULATE 關鍵字決定了物化視圖的更新策略:優化
ClickHouse 官方並不推薦使用populated,由於在建立視圖過程當中插入表中的數據並不會寫入視圖,會形成數據的丟失。
假設有一個日誌表 login_user_log
來記錄每次登陸的用戶信息,如今須要按用戶所屬地爲維度來統計天天的登陸次數。spa
PS:這種
只有新增記錄,沒有更新刪除的記錄表就很是適合使用
物化視圖
來優化統計性能
正常的聚合SQL以下:city爲用戶所屬地,login_date爲登陸時間日誌
select city, login_date, count(1) login_cnt from login_user_log group by city, login_date
增長 物化視圖
後的架構以下圖所示:code
建立基礎表:基礎表使用 SummingMergeTree
引擎,進行預聚合處理
CREATE TABLE login_user_log_base ( city String, login_date Date, login_cnt UInt32 ) ENGINE = SummingMergeTree() ORDER BY (city, login_date)
SummingMergeTree表引擎主要用於只關心聚合後的數據,而不關心明細數據的場景,它可以在合併分區的時候按照預先定義的條件聚合彙總數據,將同一分組下的多行數據彙總到一行,能夠顯著的 減小存儲空間並加快數據查詢的速度。
建立物化視圖:用戶在建立物化視圖時,經過 AS SELECT ...
子句從源表中查詢須要的列,十分靈活
CREATE MATERIALIZED VIEW if not exists login_user_log_mv TO login_user_log_base AS SELECT city, login_date, count(1) login_cnt from login_user_log group by city, login_date
使用 TO 關鍵字關聯物化視圖
與基礎表
,須要本身初始化歷史數據。
使用物化視圖查詢
SELECT city, login_date, sum(login_cnt) cnt from login_user_log_mv group by city, login_date
注意:在使用物化視圖(SummingMergeTree引擎)的時候,也須要按照聚合查詢來寫sql,由於雖然
SummingMergeTree
會本身預聚合,可是並非實時的,具體執行聚合的時機並
不可控。
掃碼關注有驚喜!