色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

ClickHouse內幕(3)基于索引的查詢優化

京東云 ? 來源:jf_75140285 ? 作者:jf_75140285 ? 2024-06-11 10:46 ? 次閱讀

ClickHouse索引采用唯一聚簇索引的方式,即Part內數據按照order by keys有序,在整個查詢計劃中,如果算子能夠有效利用輸入數據的有序性,對算子的執行性能將有巨大的提升。本文討論ClickHouse基于索引的查詢算子優化方式。

在整個查詢計劃中Sort、Distinct、聚合這3個算子相比其他算子比如:過濾、projection等有如下幾個特點:1.算子需要再內存中保存狀態,內存代價高;2.算子計算代價高;3.算子會阻斷執行pipeline,待所有數據計算完整后才會向下游輸出數據。所以上算子往往是整個查詢的瓶頸算子。

本文詳細討論,3個算子基于索引的查詢優化前后,在計算、內存和pipeline阻斷上的影響。

實驗前準備:

后續的討論主要基于實驗進行。

CREATE TABLE test_in_order
(
    `a` UInt64,
    `b` UInt64,
    `c` UInt64,
    `d` UInt64
)
ENGINE = MergeTree
ORDER BY (a, b);

表中總共有3個part,每個part數據量4條。

PS: 用戶可以在插入數據前提前關閉后臺merge,以避免part合并成一個,如果part合并成一個將影響查詢并行度,可能對實驗有影響,以下查詢可以關閉后臺merge:system stop merges test_in_order

一、Sort算子

如果order by查詢的order by字段與表的order by keys的前綴列匹配,那么可以根據數據的有序特性對Sort算子進行優化。

1.Sort算子實現方式

首先看下不能利用主鍵有序性的場景,即對于order by查詢的order by字段與表的order by keys的前綴列不匹配。比如下面的查詢:

query_1: EXPLAIN PIPELINE SELECT b FROM read_in_order ORDER BY b ASC

它的執行計劃如下:

┌─explain───────────────────────────────┐
│ (Expression)                          │
│ ExpressionTransform                   │
│   (Sorting)                           │
│   MergingSortedTransform 3 → 1        │
│     MergeSortingTransform × 3         │
│       LimitsCheckingTransform × 3     │
│         PartialSortingTransform × 3   │
│           (Expression)                │
│           ExpressionTransform × 3     │
│             (ReadFromMergeTree)       │
│             MergeTreeThread × 3 0 → 1 │
└───────────────────────────────────────┘

排序算法由3個Transform組成,其中

1)PartialSortingTransform對單個Chunk進行排序;

2)MergeSortingTransform對單個stream進行排序;

3)MergingSortedTransform合并多個有序的stream進行全局sort-merge排序

wKgaomZnupqAPI15AAB2MeV7qvk592.png


如果查詢的order by字段與表的order by keys的前綴列匹配,那么可以根據數據的有序特性對查詢進行優化,優化開關:optimize_read_in_order。

2.匹配索引列的查詢

以下查詢的order by字段與表的order by keys的前綴列匹配

query_3: EXPLAIN PIPELINE SELECT b FROM test_in_order ORDER BY a ASC, b ASCSETTINGS optimize_read_in_order = 0 -- 關閉read_in_order優化

查看order by語句的pipeline執行計劃

┌─explain───────────────────────────┐
│ (Expression)                      │
│ ExpressionTransform               │
│   (Sorting)                       │
│   MergingSortedTransform 3 → 1    │
│     MergeSortingTransform × 3     │
│       (Expression)                │
│       ExpressionTransform × 3     │
│         (ReadFromMergeTree)       │
│         MergeTreeThread × 3 0 → 1 │
└───────────────────────────────────┘

此時order by算子的算法

1)首先MergeSortingTransform對輸入的stream進行排序

2)然后MergingSortedTransform將多個排好序的stream進行合并,并輸出一個整體有序的stream,也是最終的排序結果。

這里有個疑問在關閉read_in_order優化的查詢計劃中,系統直接默認了MergeSortingTransform的輸入在Chunk內是有序的,這里其實是一個默認優化,因為order by查詢的order by字段與表的order by keys的前綴列匹配,所以數據在Chunk內部一定是有序的。

3. 開啟優化optimize_read_in_order

┌─explain──────────────────────────┐
│ (Expression)                     │
│ ExpressionTransform              │
│   (Sorting)                      │
│   MergingSortedTransform 3 → 1   │
│     (Expression)                 │
│     ExpressionTransform × 3      │
│       (ReadFromMergeTree)        │
│       MergeTreeInOrder × 3 0 → 1 │
└──────────────────────────────────┘

4. 優化分析

打開optimize_read_in_order后:

1.對于計算方面:算法中只有一個MergingSortedTransform,省略了單個stream內排序的步驟

2.由于內存方面:由于MergeSortingTransform是消耗內存最大的步驟,所以優化后可以節約大量的內存

3.對于poipeline阻塞:MergeSortingTransform會阻塞整個pipeline,所以優化后也消除了對pipeline的阻塞

二、Distinct算子

如果distinct查詢的distinct字段與表的order by keys的前綴列匹配,那么可以根據數據的有序特性對Distinct算子進行優化,優化開關:optimize_distinct_in_order。通過以下實驗進行說明:

1. Distinct算子實現方式

查看distinct語句的pipeline執行計劃

query_2: EXPLAIN PIPELINE SELECT DISTINCT * FROM woo.test_in_order SETTINGS optimize_distinct_in_order = 0 -- 關閉distinct in order優化
┌─explain─────────────────────────────┐
│ (Expression)                        │
│ ExpressionTransform                 │
│   (Distinct)                        │
│   DistinctTransform                 │
│     Resize 3 → 1                    │
│       (Distinct)                    │
│       DistinctTransform × 3         │
│         (Expression)                │
│         ExpressionTransform × 3     │
│           (ReadFromMergeTree)       │
│           MergeTreeThread × 3 0 → 1 │
└─────────────────────────────────────┘

Distinct算子采用兩階段的方式,首先第一個DistinctTransform在內部進行初步distinct,其并行度為3,可以簡單的認為有3個線程在同時執行。然后第二個DistinctTransform進行final distinct。

每個DistinctTransform的計算方式為:首先構建一個HashSet數據結構,然后根據HashSet,構建一個Filter Mask(如果當前key存在于HashSet中,則過濾掉),最后過濾掉不需要的數據。

2.開啟優化optimize_distinct_in_order

┌─explain────────────────────────────────┐
│ (Expression)                           │
│ ExpressionTransform                    │
│   (Distinct)                           │
│   DistinctTransform                    │
│     Resize 3 → 1                       │
│       (Distinct)                       │
│       DistinctSortedChunkTransform × 3 │
│         (Expression)                   │
│         ExpressionTransform × 3        │
│           (ReadFromMergeTree)          │
│           MergeTreeThread × 3 0 → 1    │
└────────────────────────────────────────┘

可以看到初步distinct和final distinct采用了不同的transform,DistinctSortedChunkTransform和DistinctTransform。

DistinctSortedChunkTransform:對單個stream內的數據進行distinct操作,因為distinct列跟表的order by keys的前綴列匹配,scan算子讀取數據的時候一個stream只從一個part內讀取數據,那么每個distinct transform輸入的數據就是有序的。所以distinct算法有:

DistinctSortedChunkTransform算法一:

Transform中保留最后一個輸入的數據作為狀態,對于每個輸入的新數據如果跟保留的狀態相同,那么忽略,如果不同則將上一個狀態輸出給上一個算子,然后保留當前的數據最為狀態。這種算法對于在整個stream內部全局去重時間和空間復雜度都有極大的降低。

wKgaomZnup2AV9P5AAAkb6cOov0046.png


DistinctSortedStreamTransform算法二:(ClickHouse采用的)

Transform對與每個Chunk(ClickHouse中Transform數據處理的基本單位,默認大約6.5w行),首先將相同的數據劃分成多個Range,并設置一個mask數組,然后將相同的數據刪除掉,最后返回刪除重復數據的Chunk。

wKgZomZnup2AVsteAAA1RbKTsnk642.png


3. 優化分析

打開optimize_distinct_in_order后:主要對于第一階段的distinct步驟進行了優化,從基于HashSet過濾的算法到基于連續相同值的算法。

1.對于計算方面:優化后的算法,省去了Hash計算,但多了判斷相等的步驟,在不同數據基數集大小下,各有優劣。

2.由于內存方面:優化后的算法,不需要存儲HashSet

3.對于poipeline阻塞:優化前后都不會阻塞pipeline

三、聚合算子

如果group by查詢的order by字段與表的order by keys的前綴列匹配,那么可以根據數據的有序特性對聚合算子進行優化,優化開關:optimize_aggregation_in_order。

1.聚合算子實現方式

查看group by語句的pipeline執行計劃:

query_4: EXPLAIN PIPELINE SELECT a FROM test_in_order GROUP BY a SETTINGS optimize_aggregation_in_order = 0 -- 關閉read_in_order優化
┌─explain─────────────────────────────┐
│ (Expression)                        │
│ ExpressionTransform × 8             │
│   (Aggregating)                     │
│   Resize 3 → 8                      │
│     AggregatingTransform × 3        │
│       StrictResize 3 → 3            │
│         (Expression)                │
│         ExpressionTransform × 3     │
│           (ReadFromMergeTree)       │
│           MergeTreeThread × 3 0 → 1 │
└─────────────────────────────────────┘

對于聚合算子的整體算法沒有在執行計劃中完整顯示出來,其宏觀上采用兩階段的聚合算法,其完整算法如下:1.AggregatingTransform進行初步聚合,這一步可以并行計算;2.ConvertingAggregatedToChunksTransform進行第二階段聚合。(PS:為簡化起見,忽略two level HashMap,和spill to disk的介紹)。

2.開啟優化optimize_aggregation_in_order

執行計劃如下:

┌─explain───────────────────────────────────────┐
│ (Expression)                                  │
│ ExpressionTransform × 8                       │
│   (Aggregating)                               │
│   MergingAggregatedBucketTransform × 8        │
│     Resize 1 → 8                              │
│       FinishAggregatingInOrderTransform 3 → 1 │
│         AggregatingInOrderTransform × 3       │
│           (Expression)                        │
│           ExpressionTransform × 3             │
│             (ReadFromMergeTree)               │
│             MergeTreeInOrder × 3 0 → 1        │
└───────────────────────────────────────────────┘

可以看到打開optimize_aggregation_in_order后aggregating算法由三個步驟組成:

1)首先AggregatingInOrderTransform會將stream內連續的相同的key進行預聚合,預聚合后在當前stream內相同keys的數據只會有一條;

2)FinishAggregatingInOrderTransform將接收到的多個stream內的數據進行重新分組使得輸出的chunk間數據是有序的,假設前一個chunk中group by keys最大的一條數據是5,當前即將輸出的chunk中沒有大于5的數據;

3)MergingAggregatedBucketTransform的作用是進行最終的merge aggregating。

wKgaomZnup2ARICmAABfrfxtQaI394.png


FinishAggregatingInOrderTransform的分組算法如下:

假設有3個stream當前算子會維護3個Chunk,每一次選取在當前的3個Chunk內找到最后一條數據的最小值,比如初始狀態最小值是5,然后將3個Chunk內所有小于5的數據一次性取走,如此反復如果一個Chunk被取光,需要從改stream內拉取新的Chunk。

wKgZomZnup6AEeZ2AABVTVDACO0969.png


這種算法保證了每次FinishAggregatingInOrderTransform向下游輸出的Chunk的最大值小于下一次Chunk的最小值,便于后續步驟的優化。

3.優化分析

打開optimize_aggregation_in_order后:主要對于第一階段的聚合步驟進行了優化,從基于HashMap的算法到基于連續相同值的算法。

1.對于計算方面:優化后的算法,減少了Hash計算,但多了判斷相等的步驟,在不同數據基數集大小下,各有優劣。

2.由于內存方面:優化前后無差別

3.對于poipeline阻塞:優化前后無差別

四、優化小結

在整個查詢計劃中Sort、Distinct、聚合這3個算子算子往往是整個查詢的瓶頸算子,所以值得對其進行深度優化。ClickHouse通過利用算子輸入數據的有序性,優化算子的算法或者選擇不同的算法,在計算、內存和pipeline阻塞三個方面均有不同程度的優化。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Pipeline
    +關注

    關注

    0

    文章

    28

    瀏覽量

    9435
  • 算子
    +關注

    關注

    0

    文章

    16

    瀏覽量

    7290
收藏 人收藏

    評論

    相關推薦

    《AI Agent 應用與項目實戰》閱讀心得3——RAG架構與部署本地知識庫

    的片段,再利用預訓練模型進行向量化,建立高效的檢索索引。在檢索階段,系統計算查詢與文檔片段的向量相似度,篩選出最相關的內容。這些內容會通過注入提示的方式提供給LLM,指導其生成準確且符合上下文的回答
    發表于 03-07 19:49

    【「基于大模型的RAG應用開發與優化」閱讀體驗】RAG基本概念

    了跨模態對齊損失函數,通過優化該函數,使得查詢語句與文檔之間的語義匹配精度得到顯著提升,從而提高檢索結果的相關性。增量索引更新技術基于LSM-Tree(Log-Structured Merge-Tree
    發表于 02-08 00:22

    【「基于大模型的RAG應用開發與優化」閱讀體驗】+第一章初體驗

    合理且正確。 三、RAG應用的技術框架 本章進一步探討了大模型與RAG結合的深層價值,提出兩者的協同效應體現在以下方面: 1數據索引階段包含:加載、分割、嵌入、索引 2數據查詢階段包含:檢索、生成
    發表于 02-07 10:42

    創建唯一索引的SQL命令和技巧

    在創建唯一索引時,以下是一些SQL命令和技巧,可以幫助優化性能: 使用合適的索引類型:對于需要保證唯一性的列,使用UNIQUE索引來避免重復數據的插入。 這可以確保列中的值是唯一的,同
    的頭像 發表于 01-09 15:21 ?149次閱讀

    javascript:void(0) 是否影響SEO優化

    使用 javascript:void(0) 確實可能對SEO優化產生負面影響 。以下是關于 javascript:void(0) 對SEO影響的具體分析: 搜索引擎爬蟲的理解問題 搜索引擎爬蟲(如
    的頭像 發表于 12-31 16:08 ?277次閱讀

    SSM框架的性能優化技巧 SSM框架中RESTful API的實現

    緩存操作。 優化SQL查詢 : SQL查詢是數據庫操作中的瓶頸之一。 使用索引來加速查詢,避免全表掃描,盡量使用
    的頭像 發表于 12-17 09:10 ?386次閱讀

    ClickHouse:強大的數據分析引擎

    作者:京東物流 陳昌浩 最近的工作中接觸到CK,一開始還不知道CK是什么,通過查詢才知道CK是ClickHouse,ClickHouse 是俄羅斯的Yandex于2016年開源的列式存儲數據庫
    的頭像 發表于 12-10 10:23 ?211次閱讀
    <b class='flag-5'>ClickHouse</b>:強大的數據分析引擎

    Taro鴻蒙技術內幕系列(一):如何將React代碼跑在ArkUI上

    基于 Taro 打造的京東鴻蒙 APP 已跟隨鴻蒙 Next 系統公測,本系列文章將深入解析 Taro 如何實現使用 React 開發高性能鴻蒙應用的技術內幕。
    的頭像 發表于 10-25 17:24 ?463次閱讀
    Taro鴻蒙技術<b class='flag-5'>內幕</b>系列(一):如何將React代碼跑在ArkUI上

    內幕揭秘:電流檢測放大器的滿量程和動態范圍注意事項

    電子發燒友網站提供《內幕揭秘:電流檢測放大器的滿量程和動態范圍注意事項.pdf》資料免費下載
    發表于 09-12 09:11 ?0次下載
    <b class='flag-5'>內幕</b>揭秘:電流檢測放大器的滿量程和動態范圍注意事項

    MATLAB中的矩陣索引

    對矩陣進行索引是從矩陣中選擇或修改部分元素的一種方式。MATLAB 有幾種索引樣式,它們不僅功能強大、靈活,而且可讀性強、表現力強。矩陣是 MATLAB 用來組織和分析數據的一個核心組件,索引是以可理解的方式有效操作矩陣的關鍵。
    的頭像 發表于 09-05 09:28 ?636次閱讀
    MATLAB中的矩陣<b class='flag-5'>索引</b>

    站群服務器真的對網站優化有用嗎?

    hncloud站群服務器(或稱為云站群服務器)是一種專門用于網站優化和SEO(搜索引優化)的服務器配置,通常用于管理多個網站和優化它們在搜索引
    的頭像 發表于 08-21 11:34 ?359次閱讀

    一文了解MySQL索引機制

    接觸MySQL數據庫的小伙伴一定避不開索引,索引的出現是為了提高數據查詢的效率,就像書的目錄一樣。 某一個SQL查詢比較慢,你第一時間想到的就是“給某個字段加個
    的頭像 發表于 07-25 14:05 ?408次閱讀
    一文了解MySQL<b class='flag-5'>索引</b>機制

    供應鏈場景使用ClickHouse最佳實踐

    關于ClickHouse的基礎概念這里就不做太多的贅述了,ClickHouse官網都有很詳細說明。結合供應鏈數字化團隊在使用ClickHouse時總結出的一些注意事項,尤其在命名方面要求研發嚴格遵守
    的頭像 發表于 07-18 15:05 ?381次閱讀
    供應鏈場景使用<b class='flag-5'>ClickHouse</b>最佳實踐

    優化嵌入式DSP軟件的編譯器

    確定哪個索引或一組索引對于優化很重要取決于應用程序開發人員的目標。例如,性能優化意味著開發人員可以使用速度較慢或成本較低的 DSP 來完成相同數量的工作。
    發表于 05-03 09:45 ?301次閱讀
    <b class='flag-5'>優化</b>嵌入式DSP軟件的編譯器

    MySQL聯表查詢優化

    條數據,本意想查出
    的頭像 發表于 04-24 12:33 ?690次閱讀
    MySQL聯表<b class='flag-5'>查詢</b><b class='flag-5'>優化</b>
    主站蜘蛛池模板: 99国产亚洲精品无码成人 | 久久精品热只有精品 | 久 久 亚洲 少 妇 无 码 | 美女脱了内裤张开腿让男人爽 | 亚洲午夜久久久久久久久电影网 | 国产色婷婷精品人妻蜜桃成熟时 | 粗大分开挺进内射 | 亚洲国产系列一区二区三区 | 亚洲日本天堂在线 | 色偷偷91综合久久噜噜 | 最近日本字幕MV免费观看在线 | 在线不卡中文字幕 | jyzzjyzzz视频国产在线观看 | 国产亚洲精品久久精品6 | 永久午夜福利视频一区在线观看 | 777午夜精品久久AV蜜臀 | 久草在线精彩免费视频 | 欧式午夜理伦三级在线观看 | 亚洲色婷婷久久精品AV蜜桃 | 春暖花开 性 欧洲 | 99精品视频在线观看re | 奇米狠狠一区二区三区 | 久久亚洲国产中文字幕 | 大桥未久电影在线观看 | 抽插的日日液液H | 精品日韩二区三区精品视频 | 973午夜伦伦电影论片 | 久久精品国产在热亚洲完整版 | 打开双腿狠狠蹂躏蜜桃臀 | 久久久无码AV精品亚洲A片软件 | 麻豆E奶女教师国产精品 | 小SAO货叫大声点妓女 | 37pao成人国产永久免费视频 | 97久久精品视频 | 国内精品久久久久久西瓜色吧 | 久久免费大片 | 男人网站在线 | jizz69女士第一次 | 亚洲精品www久久久久久 | 国产36d在线观看 | 丰满少妇67194视频 |