Clickhouse的聯合索引

Clickhouse 有了單獨的鍵索引,為什么還需要有聯合索引呢?了解過mysql的兄弟們應該都知道這個事。
對sql比較熟悉的兄弟們估計看見這個聯合索引心里大概有點數了,不過clickhouse的聯合索引相比mysql的又有些不一樣了,mysql 很遵循最左匹配原則,但是clickhouse 又似乎有些不一樣,具體哪里不一樣呢,那么我們還是和上一篇 Q220240407–clickhouse 中的索引大白話一樣,通過引用這張表hits_UserID_URL 來揭開下這個謎底。

一:聯合索引
回到hits_UserID_URL的建表語句如下,我們當時創建表的時候,我們的主鍵就指定了UserID 和URL 如下:

CREATE TABLE hits_UserID_URL
(
UserID UInt32,
URL String,
EventTime DateTime
)
ENGINE = MergeTree
PRIMARY KEY (UserID, URL)
ORDER BY (UserID, URL, EventTime);
這樣的主鍵大于1的情況,生成的那個primary.idx 索引文件(參考上一篇) 也就是會每一行都會生成n列記錄(n>1),這樣的索引文件我們就可以稱之為聯合索引文件是吧,故而UserID 和URL就形成了一個聯合索引。其實為什么需要聯合索引呢?那肯定是說在實際業務中這兩個列經常放在一起查詢,所以才會考慮給這兩個列加索引。

但是聯合索引的效果就真的好嗎,這個取決于第一列索引的基數,什么是基數呢?說白了,就是某個列的值去重之后的個數,如果個數多說明基數高,如果個數少就說明基數低;那為什么聯合索引的效果是取決于基數呢?因為聯合索引在找數據的時候是使用排除搜索法的,下面我們來講講排除搜索法

1.1: 排除搜索法

排除搜索法顧名思義就是排除掉一些數據,然后搜索一波:

因為userId 和url 是按照字典順序升序排列的,假如左邊的鍵userID 的基數比較低,那么相同的userId可能會分布在很多的grandule 里面,也就可能分布在索引標記上,如下所示:

在這里插入圖片描述

所以假如我們查詢url <=w3 的數據,那么我們就可以看看相鄰的兩個grandule的最后一個url的值和第一個url的值;如果第一個url的值是w3, 第二個url 的值是w4,那么我們需要搜索的grandule 就只有前面的第一個grandule 和 之前的grandule 里面了,如法炮制,對著前面的所有的grandule,使用二分法,就可以在小于等于 o(logn)的時間復雜度找到對應的grandule;而且需要加載的grandule 非常少,這個效率挺高

但是,哈哈哈,凡事都怕但是,在實際生產環境中,userID和url的基數可能都很高,那么相同的userID 值可能就不會分布在多個表行和grandule 中,所以索引文件中的url 值就不太可能單調遞增,如下所示:在這里插入圖片描述

這個時候使用排除搜索法估計就要全表掃描了,使用不了二分法了;這個查詢效率就賊低了,所以如果我們需要提高查找效率,就要使用多個主鍵索引了,而不是單純的用聯合索引。

二: 使用多個主鍵索引

2.1: 創建另一張表

最常見的方法就是我們再建另一張表,這張表的主鍵索引我們設置為url,如下所示:

CREATE TABLE hits_URL_UserID
(
UserID UInt32,
URL String,
EventTime DateTime
)
ENGINE = MergeTree
PRIMARY KEY (URL, UserID)
ORDER BY (URL, UserID, EventTime)
SETTINGS index_granularity = 8192, index_granularity_bytes = 0;

INSERT INTO hits_URL_UserID
SELECT * from hits_UserID_URL;

OPTIMIZE TABLE hits_URL_UserID FINAL;
這個當然可以加快查詢,但是如果我們的系統已經上線了的話,這個改動還要應用系統那邊改,不太實用

2.2: 使用物化視圖

我們可以使用物化視圖,不改動原表的情況下,如下所示:

CREATE MATERIALIZED VIEW mv_hits_URL_UserID
ENGINE = MergeTree()
PRIMARY KEY (URL, UserID)
ORDER BY (URL, UserID, EventTime)
POPULATE
AS SELECT * FROM hits_UserID_URL;

使用populate 的關鍵字是讓原表的所有值錢的數據都導入這個物化視圖,后續有的數據也會同步到這個物化視圖;

但是這個的麻煩點也和剛剛的第一種方法一樣,需要應用系統改動適配查詢物化視圖表,但是物化視圖在做聚合方面很有用,如下所示:

–agg+物化視圖本地表
–drop table if exists glab.bi_dws_lbs_adapter_agg_mv_local on cluster glab_cluster;

create materialized view glab.bi_dws_lbs_adapter_agg_mv_local on cluster glab_cluster(
id String,
idType AggregateFunction(argMax, String, UInt64 ),
geohash AggregateFunction(argMax, String, UInt64 ),
locType AggregateFunction(argMax, Int64, UInt64 ),
wifimac AggregateFunction(argMax, String, UInt64 ),
ip AggregateFunction(argMax, String, UInt64 ),
baseStation AggregateFunction(argMax, String, UInt64 ),
connectType AggregateFunction(argMax, Int64, UInt64 ),
equipmentId AggregateFunction(argMax, String, UInt64 ),
time AggregateFunction(max, UInt64 )
)
engine = AggregatingMergeTree()
partition by tuple()
order by id
as
select
id,
argMaxState ( id_type, ts ) AS idType,
argMaxState ( geohash12, ts ) AS geohash,
argMaxState ( loc_type, ts ) AS locType,
argMaxState ( wifimac, ts ) AS wifimac,
argMaxState ( ip, ts ) AS ip,
argMaxState ( base_station, ts ) AS baseStation,
argMaxState ( connect_type, ts ) AS connectType,
argMaxState ( equipment_id, ts ) AS equipmentId,
maxState( ts ) AS time
from glab.bi_dws_lbs_adapter_local
where geohash12 != ‘’ AND geohash12 IS NOT NULL
group by id;

–agg+物化視圖集群表
CREATE TABLE glab.bi_dws_lbs_adapter_agg_mv on cluster glab_cluster as bi_dws_lbs_adapter_agg_mv_local
ENGINE = Distributed(‘glab_cluster’, ‘glab’, ‘bi_dws_lbs_adapter_agg_mv_local’, murmurHash3_32(id))

參考鏈接:https://cf.cloudglab.cn/pages/viewpage.action?pageId=226211113

2.3: 使用投影projection

上述兩個方法都是需要應用系統適配,但是這個projection 就很好的解決了這個問題,BI這邊改動就行,不需要應用改動,如下所示:

ALTER TABLE hits_UserID_URL
ADD PROJECTION prj_url_userid
(
SELECT *
ORDER BY (URL, UserID)
);

ALTER TABLE hits_UserID_URL
MATERIALIZE PROJECTION prj_url_userid; (使用materalize 是為了讓原始的數據形成另一個索引)

所以當系統查詢慢的情況下,如果就是因為聯合索引的問題,我們可以使用projection,成本最小;如果需要查詢諸如max(ts) 的geohash ,那就要用到物化視圖了。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/43940.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/43940.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/43940.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深入解析Spring Boot的application.yml配置文件

目錄 引言Spring Boot配置文件簡介 application.yml的優點 基本結構與語法 YAML語法基礎Spring Boot中application.yml的基本結構 常見配置項詳解 服務器配置數據源配置日志配置其他常見配置 環境配置與Profile 多環境配置激活Profile 高級配置與技巧 屬性的占位符替換自定義配…

Spring源碼二十:Bean實例化流程三

上一篇Spring源碼十九&#xff1a;Bean實例化流程二中&#xff0c;我們主要討論了單例Bean創建對象的主要方法getSingleton了解到了他的核心流程無非是&#xff1a;通過一個簡單工廠的getObject方法來實例化bean&#xff0c;當然spring在實例化前后提供了擴展如&#xff1a;bef…

第5章-組合序列類型

#全部是重點知識&#xff0c;必須會。 了解序列和索引|的相關概念 掌握序列的相關操作 掌握列表的相關操作 掌握元組的相關操作 掌握字典的相關操作 掌握集合的相關操作1&#xff0c;序列和索引 1&#xff0c;序列是一個用于存儲多個值的連續空間&#xff0c;每一個值都對應一…

升級之道:精通Conda的自我升級藝術

升級之道&#xff1a;精通Conda的自我升級藝術 引言 Conda是Python和其他科學計算語言的強大包管理器&#xff0c;它不僅管理著包的安裝和依賴&#xff0c;還負責自身的更新。隨著開源社區的不斷發展&#xff0c;Conda定期發布新版本以修復已知問題、增加新功能和提高性能。本…

[面試愛問] https 的s是什么意思,有什么作用?

HTTPS 中的 "S" 代表 "Secure"&#xff0c;即安全的意思。HTTPS&#xff08;全稱是 HyperText Transfer Protocol Secure&#xff09;是HTTP&#xff08;HyperText Transfer Protocol&#xff09;的安全版本&#xff0c;主要作用是為互聯網通信提供安全保護…

靈活多變的對象創建——工廠方法模式(Python實現)

1. 引言 大家好&#xff0c;又見面了&#xff01;在上一篇文章中&#xff0c;我們聊了聊簡單工廠模式&#xff0c;今天&#xff0c;我們要進一步探討一種更加靈活的工廠設計模式——工廠方法模式。如果說簡單工廠模式是“萬能鑰匙”&#xff0c;那工廠方法模式就是“變形金剛”…

生成式人工智能:助攻開發者還是取代開發者?

引言 近年來&#xff0c;生成式人工智能&#xff08;AIGC&#xff09;在軟件開發領域掀起了一場革命&#xff0c;為開發者帶來了全新的工具和可能性。從代碼生成、錯誤檢測到自動化測試&#xff0c;AI正在以各種方式改變著開發者的工作方式。然而&#xff0c;這也引發了人們對開…

Python采集京東標題,店鋪,銷量,價格,SKU,評論,圖片

京東的許多數據是通過 JavaScript 動態加載的&#xff0c;包括銷量、價格、評論和評論時間等信息。我們無法僅通過傳統的靜態網頁爬取方法獲取到這些數據。需要使用到如 Selenium 或 Pyppeteer 等能夠模擬瀏覽器行為的工具。 另外&#xff0c;京東的評論系統是獨立的一個系統&a…

offer題目33:判斷是否是二叉搜索樹的后序遍歷序列

題目描述&#xff1a;輸入一個整數數組&#xff0c;判斷該數組是不是某二叉搜索樹的后序遍歷結果。如果是則返回true,否則返回false。假設輸入的數組的任意兩個數字都互不相同。例如&#xff0c;輸入數組{5,7,6,9,11,10,8},則返回true,&#xff0c;因為這個整數是下圖二叉搜索樹…

c++內存管理(上)

目錄 引入 分析 說明 C語言中動態內存管理方式 C內存管理方式 new/delete操作內置類型 new和delete操作自定義類型 引入 我們先來看下面的一段代碼和相關問題 int globalVar 1; static int staticGlobalVar 1; void Test() { static int staticVar 1; int localVar 1…

集訓day3:并查集

一、目錄 1.并查集模版 2.并查集的理解和應用 二、正文 1.并查集模版 P3367 【模板】并查集 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn) 2.并查集的理解與應用 (1).并查集與聯通塊數量 P1197 [JSOI2008] 星球大戰 - 洛谷 | 計算機科學教育新生態 (luogu.com.cn) P1656 炸…

數圖助推朝陽佳惠遼寧華聯開啟數字化導航、精細化管理新紀元!

近期&#xff0c;遼寧省著名零售企業朝陽佳惠與遼寧華聯&#xff0c;秉持創新精神&#xff0c;大膽嘗試&#xff0c;在品類空間管理方面推出了創新舉措。引入了先進的數圖可視化陳列管理系統&#xff0c;通過智能化、直觀化的方式優化商品布局。此舉不僅大幅提高了商品管理的效…

去除各種軟件彈窗教程

清羽彈窗 在mutil/OnlineDialog/onPostExecute前 添加return-void Arm彈窗 第一步&#xff0c;提取安裝包 第二步&#xff0c;搜索代碼Ljava/io/DataOutputStream;->flush()V 第三步&#xff0c;往上看找到 .registers 10 在下面加return-void 云注入彈窗 第一種方法:dex搜…

Sql 導入到 Excel 工具

Sql 導入到 Excel 工具 這個VBA宏的步驟如下&#xff1a; 通過文件對話框選擇SQL文件。讀取文件內容。解析文件中的每一行&#xff0c;如果包含“insert into”&#xff0c;則提取表名。檢查是否已經存在以表名命名的工作表&#xff0c;如果不存在則創建新的工作表。將數據插…

element-ui封裝分頁組件:實現首頁、上一頁、下一頁、末頁、跳轉按鈕

首頁、上一頁、下一頁、末頁、跳轉按鈕 因為el-pagination只有一個插槽&#xff0c;所以通過兩個el-pagination插槽分別加入首頁、末頁按鈕&#xff0c;再拼接這兩個el-pagination的方式來實現首頁、末頁按鈕跳轉按鈕不用加事件&#xff0c;如果el-pagination修改了前往的頁數…

【work】AI八股-神經網絡相關

Deep-Learning-Interview-Book/docs/深度學習.md at master amusi/Deep-Learning-Interview-Book GitHub 網上相關總結&#xff1a; 小菜雞寫一寫基礎深度學習的問題&#xff08;復制大佬的&#xff0c;自己復習用&#xff09; - 知乎 (zhihu.com) CV面試問題準備持續更新貼 …

VOI(Virtual Operating System Infrastructure,虛擬操作系統基礎架構)

VOI&#xff08;Virtual Operating System Infrastructure&#xff0c;虛擬操作系統基礎架構&#xff09;架構在桌面虛擬化領域具有其獨特的優勢&#xff0c;使得它在某些場景下表現尤為出色。以下是幾個具體場景&#xff1a; 1. 重載性能需求場景 表現&#xff1a; 高效利用…

聚類分析方法(二)

目錄 三、層次聚類方法&#xff08;一&#xff09;層次聚類策略&#xff08;二&#xff09;AGNES算法&#xff08;三&#xff09;DIANA算法 四、密度聚類方法&#xff08;一&#xff09;基本概念&#xff08;二&#xff09;算法描述&#xff08;三&#xff09;計算實例&#xf…

Google賬號輸入用戶名和密碼后提醒要到手機通知點是,還要點擊數字,但是我手機收不到

有一些朋友換了一個新的電腦后手機登錄谷歌賬號時&#xff0c;用戶名和密碼都正確輸入以后&#xff0c;第三步彈出一個提示&#xff0c;要在手機上的通知欄點擊是&#xff0c;并且點擊手機上相應的數字才能繼續登錄。 但是自己的手機上下拉通知欄卻沒有來自谷歌的通知&#xf…

ADOQuery 查詢MSSQL存儲過程一個莫名其妙的錯誤;

在 SSMS 中執行完成正常的的存儲過程。 也能正常的返回想要的數據&#xff0c;&#xff0c;然后通過 ADO 查詢時&#xff0c;總是提法 某 字段不存在的問題&#xff1b; 此問題困擾了一天。 例如&#xff08;當然&#xff0c;實際數據結構比下面舉例的復雜&#xff09;&…