日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

19_clickhouse,数据查询与写入优化,分布式子查询优化,外部聚合/排序优化,基于JOIN引擎的优化,SQL优化案例,物化视图提速,查询优化常用经验法则,选择和主键不一样的排序键,数据入库优化

發布時間:2024/9/27 数据库 35 豆豆

25.數據查詢與寫入優化
25.1.分布式子查詢優化
25.1.1.分布式表的IN查詢示例1(普通IN子查詢、IN子查詢為本地表)
25.1.2.分布式表的IN查詢示例2(普通IN子查詢、IN子查詢為分布式表)
25.1.3.分布式表的IN查詢示例3(GLOBAL IN子查詢、IN子查詢為分布式表)
25.1.4.使用GLOBAL IN/GLOBAL JOIN注意事項
25.2.外部聚合/排序優化
25.3.基于JOIN引擎的優化
25.4.SQL優化案例
25.4.1.物化視圖提速
25.4.2.查詢優化常用經驗法則
25.4.3.選擇和主鍵不一樣的排序鍵
25.4.4.數據入庫優化

25.數據查詢與寫入優化

25.1.分布式子查詢優化

帶子查詢的IN和JOIN有兩個選項:普通的IN/JOIN、GLOBAL IN / GLOBAL JOIN。
1、 普通的IN/JOIN : 查詢發送到遠程的server,在每個遠程的server上運行IN子查詢或JOIN子句。
2、 GLOBAL IN/GLOBAL JOIN : 首先為GLOBAL IN/GLOBAL JOIN運行所有子查詢,將結果收集在臨時表中。然后將臨時表發送到每個遠端server,并在其中使用此臨時數據運行查詢。

25.1.1.分布式表的IN查詢示例1(普通IN子查詢、IN子查詢為本地表)

SELECT uniq(UserID) FROM distributed_tableWHERE UserID IN (SELECT UserID FROM local_table_in WHERE CounterID = 34);

上面的查詢語句將被發送到所有遠程服務器上, 并在遠程服務器使用本地表運行:

SELECT uniq(UserID) FROM local_table WHERE UserID IN (SELECT UserID FROM local_table_in WHERE CounterID=34);

上面的語句需要保證該local_table_in表的所有USERID完全駐留在單個服務器上,否則,數據可能會不準確。

25.1.2.分布式表的IN查詢示例2(普通IN子查詢、IN子查詢為分布式表)

SELECT uniq(UserID) FROM distributed_tableWHERE UserID IN (SELECT UserID FROM distributed_table_in WHERE CounterID = 34);

1.上面的查詢語句將被發送到所有遠程服務器上(假設100臺服務器),并被遠程服務器使用本地表運行:

SELECT uniq(UserID) FROM local_table WHERE UserID IN (SELECT UserID FROM distributed_table_in WHERE CounterID = 34);

2.由于子查詢是分布式表,每個子查詢分發至100臺服務器,運行如下查詢:

SELECT UserID FROM local_table_in WHERE CounterID = 34;

執行整個查詢需要100 * 100 = 10000個請求。這將導致嚴重性能問題。

考慮使用GLOBAL IN。

25.1.3.分布式表的IN查詢示例3(GLOBAL IN子查詢、IN子查詢為分布式表)

SELECT uniq(UserID) FROM distributed_table WHERE UserID GLOBAL IN (SELECT UserID FROM distributed_table_in WHERE CounterID = 34);

1.在請求服務器上運行子查詢,并將結果存儲在RAM的臨時表_data1中。

SELECT UserID FROM distributed_table_in WHERE CounterID = 34;

2.請求服務器將臨時表_data1發送到每個遠程的服務器上,并在每個服務器執行如下查詢:

SELECT uniq(UserID) FROM local_table WHERE UserID IN _data1;

避免了普通IN導致的連鎖響應請求。

25.1.4.使用GLOBAL IN/GLOBAL JOIN注意事項

1.使用GLOBAL IN創建臨時表,數據沒有去重。若要減少網絡傳輸的數據量, 在子查詢中指定 DISTINCT。
2.使用GLOBAL時,應盡量避免使用大數據集。臨時表將發送所有遠程的主機,特別是在多機房容災的集群架構下,數據發送至遠程數據中心性能低下。
3.GLOBAL可能會導致網絡超載。不會限制網絡帶寬。
4.使用GLOBAL時,盡量保證副本組駐留在同一個數據中心,保證快速的網絡數據傳輸。
5.為避免GLOBAL導致的數據傳輸,可提前將全量的數據發至每個節點,并使用普通JOIN/IN。

25.2.外部聚合/排序優化

聚合查詢消耗的內存超過max_memory_usage(默認10G)設置的值,導致內存溢出。

ClickHouse支持將臨時數據轉儲到磁盤以限制GROUP BY期間的內存使用。

當GROUP BY消耗超過max_bytes_before_external_group_by設置的閾值,ClickHouse將中間數據轉儲到磁盤。默認值為0,表示禁用磁盤溢寫。

聚合有兩個階段,第一階段讀取數據并形成中間數據。第二階段合并中間數據。中間臨時數據轉儲到磁盤是發生在第一階段,如果沒有數據轉儲,則兩個階段使用的內存相同。

在設置max_bytes_before_external_group_by值時,建議將其設置為max_memory_usage的一半。

當使用分布式查詢,為了保證外部聚合時在遠程的server端執行,設置 distributed_aggregation_memory_efficient為1。

開啟外部排序設置max_bytes_before_external_sort,否則可能會內存不足導致查詢異常終止。

當啟用外部聚合,如果數據沒有轉儲到磁盤,此時,查詢的運行速度和沒有外部聚合時一樣快。 如果中間數據轉儲到磁盤,則運行時間將延長數倍(大約3倍)。
而外部排序,數據轉儲到磁盤,性能將明顯下降。
三個參數分別設置為20GB、10GB和40GB。

1.在命令行界面設置:

set max_bytes_before_external_group_by=20000000000; set max_bytes_before_external_sort=10000000000; set max_memory_usage=40000000000;

2.JDBC設置,在URL添加參數:

url?max_bytes_before_external_group_by=20000000000&max_memory_usage=40000000000

25.3.基于JOIN引擎的優化

如果多次使用相同的表(子查詢),每次都需要重新計算運行子查詢。為此,可使用Join表引擎將數據緩存在 RAM中。
語法:

ENGINE=Join(join_strictness,join_type,k1[,k2,...]) 參數: join_strictness,取值ALL,ANY和ASOF join_type : JOIN的類型,LEFTRIGHTINNER等。 k1[,k2,...] : 關聯的字段

JOIN引擎使用示例:
創建表:

DROP TABLE id_val; CREATE TABLE id_val(`id` UInt32, `val` UInt32) ENGINE = TinyLog;

插入表數據:

INSERT INTO id_val VALUES (1,11)(2,12)(3,13);

創建右連接的JOIN引擎表:

DROP TABLE id_val_join; CREATE TABLE id_val_join(`id` UInt32, `val` UInt8) ENGINE = Join(ANY, LEFT, id);

插入數據:

INSERT INTO id_val_join VALUES (1,21)(1,22)(3,23);

表數據關聯:
SELECT * FROM id_val ANY LEFT JOIN id_val_join USING (id) SETTINGS join_use_nulls = 1;

25.4.SQL優化案例

25.4.1.物化視圖提速

在用于插入數據的表上,創建多個物化視圖,每個物化視圖根據業務需求對數據做轉換。

1.物化視圖存儲通過由相應的SELECT查詢轉換的數據。
2.在數據插入期間做查詢轉換,壓力分散。
3.僅在插入的單個數據塊中聚合,數據不會進一步聚合。
4.數據表的引擎可為NULL。

25.4.2.查詢優化常用經驗法則

1.小表放在JOIN的右邊
2.使用子查詢顯示設置數據處理的順序
3.使用IN替換JOIN操作
4.使用字典替換JOIN操作。
5.設置單射屬性。
6.使用Join引擎緩存表。
7.禁用分布式表的子查詢,使用GLOBAL IN/JOIN替換或者將子查詢的表提前分發至所有的server作為本地表。
8.使用PREWHERE
9.避免使用SELECT *查詢
10.盡量少用或不用多表關聯。

25.4.3.選擇和主鍵不一樣的排序鍵

默認情況下,主鍵(由PRIMARY KEY指定)跟排序鍵(ORDER BY)相同,因此,大部分情況下,不需要專門指定一個PRIMARY KEY子句。

當使用SummingMergeTree 和 AggregatingMergeTree時,可考慮選擇和主鍵不一樣的排序鍵。

CREATE TABLE t_merge_sum (id UInt32, name String, value UInt32 )ENGINE = SummingMergeTree() PRIMARY KEY id ORDER BY (id,name);

1.排序鍵可以修改,主鍵不能修改。
2.預聚合/增量聚合的key是由排序鍵指定的。業務邏輯后期可能會更改。
3.查詢條件無需包括排序鍵的所有字段。

添加排序鍵需要注意的:
1.主鍵字段是排序鍵字段的子集。
例如主鍵為(A,B),則排序鍵以(A,B)開頭,排序鍵可為(A,B)或(A,B,C)等。

2.舊的排序鍵是新的排序鍵的前綴。
修改排序鍵只能增加排序字段,不能減少排序鍵字段,例如可修改排序鍵(A,B)為(A,B,C),但不能修改為(A,C)或(A,C,B)等。

3.排序鍵只能添加新加入表的列,表中已存在的數據的列不能添加到排序鍵中。

25.4.4.數據入庫優化

分布式表本地表
簡單數據通過各節點的本地表導入
異步發送壓力分散
無一致性校驗原子寫入
ZooKeeper壓力大

1.使用復制表,能夠保證數據原子寫入和去重。
2.限制單個復制表INSERT語句執行的頻率(建議每秒不超過1個)
3.以相當大的數據塊插入數據(默認為1048576)。
4.將數據INSERT到ClickHouse之前,通過分區鍵對數據進行分組。
5.增加入庫的并發,入庫性能線性提升。
6.自定義負載均衡策略,控制數據均衡。

總結

以上是生活随笔為你收集整理的19_clickhouse,数据查询与写入优化,分布式子查询优化,外部聚合/排序优化,基于JOIN引擎的优化,SQL优化案例,物化视图提速,查询优化常用经验法则,选择和主键不一样的排序键,数据入库优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。