騰龍【大資料clickhouse】clickhouse 常用查詢最佳化策略詳解
騰龍娛樂公司註冊網址官網[k578.net]比如,當查詢列明顯多於篩選列時使用 Prewhere 可十倍提升查詢效能, Prewhere 會自動最佳化
執行過濾階段的資料讀取方式,降低 io 操作。某些場景下, prewhere 語句比 where 語句處理的資料量更少效能更高。
舉例來說,我們在使用mysql查詢一條資料,如下面的這條sql,在不考慮索引的情況下,正常的執行過程是,先掃描表的資料,然後過濾出name='xxx'的符合條件的記錄;
select u.* from user u where u.name = 'xxx'
在clickhouse中,預設情況下,使用where 過程也是類似,但使用了Prewhere 時,並不需要進行全表的掃描了,這樣就大大提升了查詢的效能;
預設情況下,prewhere自動開啟
看下面的查詢sql,使用explain檢視下
EXPLAIN SYNTAX
select WatchID,
JavaEnable,
Title,
GoodEvent,
EventTime,
EventDate,
CounterID,
ClientIP,
ClientIP6,
RegionID,
UserID,
CounterClass,
OS,
UserAgent,
URL,
Referer,
URLDomain,
RefererDomain,
Refresh,
IsRobot,
RefererCategories,
URLCategories,
URLRegions,
RefererRegions,
ResolutionWidth,
ResolutionHeight,
ResolutionDepth,
FlashMajor,
FlashMinor,
FlashMinor2
from datasets.hits_v1 where UserID='3198390223272470366';
可以看到引擎自動最佳化為了prewhere查詢
關閉 where 自動轉 prewhere
開啟下面的配置,可以關閉prewhere功能
set optimize_move_to_prewhere=0;
再次查詢,可以發現prewhere就關閉了;
預設情況,肯定不會關閉 where ,引擎會 自動最佳化為 prewhere ,但某些場景即使開啟優
化,也不會自動轉換成 prewhere ,需要手動指定 prewhere,如下:
使用常量表示式;
使用預設值為 alias 型別的欄位;
包含了 arrayJOIN,globalIn,globalNotIn 或者 indexHint 的查詢;
select 查詢的列欄位和 where 的謂詞相同;
使用了主鍵欄位;
比如下面的sql,在這種情況下就不會使用 prewhere ;
2.2 使用資料取樣替代全量查詢或統計
在某些情況下,比如資料量為TB級別的甚至更大的情況下,不需要精確對資料進行統計而是一個預估值時,可以透過取樣運算,這樣可極大提升資料分析的效能;
SAMPLE 0.1 # 代表取樣 10% 的資料 , 也可以是具體的條數
SELECT Title,count(*) AS PageViews
FROM hits_v1
SAMPLE 0.1
WHERE CounterID =57
GROUP BY Title
ORDER BY PageViews DESC LIMIT 1000;
可以發現使用這種方式計算統計結果時效能上有明顯的提升;
2.3 列裁剪與分割槽裁剪
列裁剪(減少非必要的查詢欄位)
表的資料量太大時,應儘量避免使用 select * 操作,一般來說,查詢的效能會與查詢的欄位大小和數量成線性增長,欄位越少,消耗的 io 資源越少,效能就會越高;
比如下面這樣的sql,就是需要儘量避免的(小編測試在當前伺服器下執行介面直接崩掉了);
select * from datasets.hits_v1;
改成下面這樣就會好很多;
select WatchID,
JavaEnable,
Title,
GoodEvent,
EventTime,
EventDate,
CounterID,
ClientIP,
ClientIP6,
RegionID,
UserID
from datasets.hits_v1;
分割槽裁剪
就是隻讀取需要的分割槽,在過濾條件中指定
select WatchID,
JavaEnable,
Title,
GoodEvent,
EventTime,
EventDate,
CounterID,
ClientIP,
ClientIP6,
RegionID,
UserID
from datasets.hits_v1
where EventDate='2014-03-23';
2.4 orderby 結合 where、limit
千萬量級以上的資料集進行 order by 查詢時,最好搭配 where 條件和 limit 語句一起使用,說到底,就是對查詢的結果集數量進行限制,資料量減少了怎麼都好說;
SELECT
UserID,Age
FROM
hits_v1
WHERE
CounterID=57
ORDER BY Age DESC LIMIT 1000;
2.5 避免構建虛擬列
如非必須,不要在結果集上構建虛擬列,虛擬列非常消耗資源浪費效能,可以考慮在前端進行處理,或者在表中構造實際欄位進行額外儲存;
比如下面的sql,Income/Age 這個就是一個虛擬列,表中並不存在這個欄位,而是處於業務的需要構建出來的,不僅是clickhouse,甚至mysql中這種寫法也應該是儘量要避免的;
SELECT Income,Age,Income/Age as IncRate FROM datasets.hits_v1;
2.6 使用uniqCombined 替代 distinct
使用uniqCombined 替代 distinct ,效能可提升 10 倍以上,uniqCombined 底層採用類似 HyperLogLog 演算法實現,能接收 2%左右的資料誤差,可直接使用這種去重方式提升查詢效能;
Count(distinct )會使用 uniqExact精確去重,不建議在千萬級不同資料上執行 distinct 去重查詢,改為近似去重 uniqCombined;
比如查詢時可以使用下面這種方式
SELECT uniqCombined(rand()) from datasets.hits_v1;
2.7 其他單表查詢中需要注意的事項
(一)查詢熔斷
為了避免因個別慢查詢引起服務雪崩問題,除了可以為單個查詢設定超時以外,還可以配置週期熔斷,在一個查詢週期內,如果使用者頻繁進行慢查詢操作超出規定閾值後將無法繼續進行查詢操作。
(二)關閉虛擬記憶體
實體記憶體和虛擬記憶體的資料交換,會導致查詢變慢,資源允許的情況下建議關閉虛擬記憶體;
(三)配置 join_use_nulls
為每一個賬戶新增 join_use_nulls 配置,左表中的一條記錄在右表中不存在,右表的相應欄位會返回該欄位相應資料型別的預設值,而不是標準 SQL 中的 Null 值;
(四)批次寫入時先排序
批次寫資料時,必須控制每個批次的資料中涉及到的分割槽的數量,在寫入之前最好對需要匯入的資料進行排序。因為無序的資料或者涉及的分割槽太多,會導致 ClickHouse 無法及時對新匯入的資料進行合併,從而影響查詢效能。
(五)關注 CPU
cpu 一般在 50%左右會出現查詢波動,達到 70%會出現大範圍的查詢超時,cpu 是最關
鍵的指標,因此運維過程中要非常關注。
三、關於多表關聯查詢相關最佳化策略
前置準備
依次執行下面的sql,從源表中複製出兩個新表,並從源表中匯入部分資料
#建立小表
CREATE TABLE visits_v2
ENGINE = CollapsingMergeTree(Sign)
PARTITION BY toYYYYMM(StartDate)
ORDER BY (CounterID, StartDate, intHash32(UserID), VisitID)
SAMPLE BY intHash32(UserID)
SETTINGS index_granularity = 8192
as select * from visits_v1 limit 10000;
#建立 join 結果表:避免控制檯瘋狂列印資料
CREATE TABLE hits_v2
ENGINE = MergeTree()
PARTITION BY toYYYYMM(EventDate)
ORDER BY (CounterID, EventDate, intHash32(UserID))
SAMPLE BY intHash32(UserID)
SETTINGS index_granularity = 8192
as select * from hits_v1 where 1=0;
3.1 使用in代替join
當多表聯合查詢時,當最終查詢的資料僅從其中一張表出來時,可考慮用 IN 操作而不是使用JOIN
這個和clickhouse的自身的關聯查詢資料載入機制有關,比如A join B時,需要先把B載入到記憶體中,然後從A中查詢的結果跟記憶體中B的資料進行匹配,如果B表的資料量非常大,很有可能造成記憶體被耗盡;
————————————————
版權宣告:本文為CSDN博主「逆風飛翔的小叔」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/congge_study/article/details/128271948
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70026759/viewspace-2936155/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ClickHouse內幕(3)基於索引的查詢最佳化索引
- ClickHouse的查詢效能優勢
- Clickhouse-客戶端查詢命令客戶端
- Clickhouse Engine kafka 將kafka資料同步clickhouseKafka
- 資料來源管理 | OLAP查詢引擎,ClickHouse叢集化管理
- ClickHouse為什麼查詢速度快?
- ClickHouse資料副本引擎
- clickhouse 同步mysql資料MySql
- ClickHouse(19)ClickHouse整合Hive表引擎詳細解析Hive
- ClickHouse(18)ClickHouse整合ODBC表引擎詳細解析
- ClickHouse(17)ClickHouse整合JDBC表引擎詳細解析JDBC
- ClickHouse(16)ClickHouse日誌引擎Log詳細解析
- 30個MySQL千萬級大資料SQL查詢最佳化技巧詳解MySql大資料
- 資料庫圈周盤點:ClickHouse宣佈推出ClickHouse Cloud資料庫Cloud
- clickhouse-mysql資料同步MySql
- 二、ClickHouse 資料型別資料型別
- ClickHouse、Doris、 Impala等MPP架構詳解架構
- ClickHouse在大資料領域應用實踐大資料
- FlinkCDCSQL資料同步mysql->clickhouseMySql
- ReplacingMergeTree:實現Clickhouse資料更新
- clickhouse資料型別簡介資料型別
- 圖解大資料 | 海量資料庫查詢-Hive與HBase詳解圖解大資料資料庫Hive
- 騰訊雲ClickHouse如何實現自動化的資料均衡?
- [Clickhouse] Clickhouse 報SQLException : Read timed outSQLException
- ClickHouse(04)如何搭建ClickHouse叢集
- ClickHouse叢集資料均衡方案分享
- clickhouse 億級資料效能測試
- ClickHouse(15)ClickHouse合併樹MergeTree家族表引擎之GraphiteMergeTree詳細解析
- ClickHouse(13)ClickHouse合併樹MergeTree家族表引擎之CollapsingMergeTree詳細解析
- ClickHouse(12)ClickHouse合併樹MergeTree家族表引擎之AggregatingMergeTree詳細解析
- ClickHouse(11)ClickHouse合併樹MergeTree家族表引擎之SummingMergeTree詳細解析
- TB 級資料入庫無壓力:Apache DolphinScheduler 助力 ClickHouse 最佳化Apache
- ClickHouse(01)什麼是ClickHouse,ClickHouse適用於什麼場景
- [clickhouse] Clickhouse之開窗函式篇函式
- Install clickhouse
- 使用 Apache Superset 視覺化 ClickHouse 資料Apache視覺化
- 【clickhouse專欄】clickhouse效能為何如此卓越
- ClickHouse(03)ClickHouse怎麼安裝和部署