ClickHouse性能優化?試試物化視圖

1、前言

ClickHouse是一個用於聯機分析(OLAP)的列式數據庫管理系統(DBMS);目前咱們使用CH做爲實時數倉用於統計分析,在作性能優化的時候使用了 物化視圖 這一特性做爲優化手段,本文主要分享物化視圖的特性與如何使用它來優化ClickHouse的查詢性能。sql

 

2、概念

數據庫中的 視圖(View) 指的是經過一張或多張表查詢出來的 邏輯表 ,自己只是一段 SQL 的封裝並 不存儲數據數據庫

物化視圖(Materialized View) 與普通視圖不一樣的地方在於它是一個查詢結果的數據庫對象(持久化存儲),很是趨近於表;物化視圖是數據庫中的預計算邏輯+顯式緩存,典型的空間換時間思路,因此用得好的話,它能夠避免對基礎表的頻繁查詢並複用結果,從而顯著提高查詢的性能。緩存

在傳統關係型數據庫中,Oracle、PostgreSQL、SQL Server等都支持物化視圖,而做爲MPP數據庫的ClickHouse也支持該特性。性能優化

file

 

3、ClickHouse物化視圖

ClickHouse中的物化視圖能夠掛接在任意引擎的基礎表上,並且會自動更新數據,它能夠藉助 MergeTree 家族引擎(SummingMergeTree、Aggregatingmergetree等),獲得一個實時的預聚合,知足快速查詢;可是對 更新刪除 操做支持並很差,更像是個插入觸發器。架構

建立語法:性能

CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...

POPULATE 關鍵字決定了物化視圖的更新策略:優化

  • 如有POPULATE 則在建立視圖的過程會將源表已經存在的數據一併導入,相似於 create table ... as
  • 若無POPULATE 則物化視圖在建立以後沒有數據
ClickHouse 官方並不推薦使用populated,由於在建立視圖過程當中插入表中的數據並不會寫入視圖,會形成數據的丟失。

 

4、案例

4.1. 場景

假設有一個日誌表 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

file

 

4.2. 建表

建立基礎表:基礎表使用 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 關鍵字關聯 物化視圖基礎表,須要本身初始化歷史數據。

 

4.3. 查詢統計結果

使用物化視圖查詢

SELECT city, login_date, sum(login_cnt) cnt
from login_user_log_mv
group by city, login_date
注意:在使用物化視圖(SummingMergeTree引擎)的時候,也須要按照聚合查詢來寫sql,由於雖然 SummingMergeTree 會本身預聚合,可是並非實時的,具體執行聚合的時機並 不可控

 

總結

  1. 在建立 MV 表時,必定要使用 TO 關鍵字爲 MV 表指定存儲位置,不然不支持 嵌套視圖(多個物化視圖繼續聚合一個新的視圖)
  2. 在建立 MV 表時若是用到了多表聯查,不能爲鏈接表指定別名,若是多個鏈接表中存在同名字段,在鏈接表的查詢語句中使用 AS 將字段名區分開
  3. 在建立 MV 表時若是用到了多表聯查,只有當第一個查詢的表有數據插入時,這個 MV 纔會被觸發
  4. 在建立 MV 表時不要使用 POPULATE 關鍵字,而是在 MV 表建好以後將數據手動導入 MV 表
  5. 在使用 MV 的聚合引擎時,也須要按照聚合查詢來寫sql,由於聚合時機不可控

 

掃碼關注有驚喜!

file

相關文章
相關標籤/搜索