主頁 > 資料庫 > HStore表全了解:實時入庫與高效查詢利器

HStore表全了解:實時入庫與高效查詢利器

2023-06-15 08:42:40 資料庫

摘要:本文章將從使用者角度介紹HStore概念以及使用,

本文分享自華為云社區《GaussDB(DWS)HStore表講解》,作者:大威天龍:- ,

HStore表簡介

面對實時入庫和實時查詢要求越來越高的趨勢,已有的列存盤無法支持并發更新入庫,行存查詢性能無法做到實時回傳且空間壓縮表現不佳,GaussDB(DWS)基于列存盤格式設計和實作了全新的HStore表,同時提供高效的并發插入、更新入庫,以及高性能實時查詢,本文章將從使用者角度介紹HStore概念以及使用,

HStore表的背景

為什么要有HStore表呢?在具體講解HStore表之前,我們先來回顧一下GaussDB(DWS)中幾種已有的表型別:

行存表(row-store)

最基礎的表型別,顧名思義,資料按行存盤,在實際的物理塊中,資料的將按下列圖示的方式存盤:

優勢很明顯,點查場景下,直接就能索引到行存某行元組的位置,點查性能好,資料庫中的系統表就是行存表,對于用戶的一些對點查性能要求高或者頻繁更新的小表,都推薦用行存表,

列存表(column-store)

AP場景下,常常需要對某列進行批量查詢來做分析業務,這時候采用行存的話就會把所有列都讀出來產生冗余IO, 同時AP場景下的表資料量往往很大,行存表壓縮暫未商用,使用行存表也會導致占用空間過大,

GaussDB(DWS)中的列存表就是針對這種場景實作的,列存表資料的實際存盤示意圖如下:

列存表將每列的資料批量存盤成一個CU(Compress Unit), 能帶來了很好的空間壓縮與批量查詢性能提升,對于一些涉及多表關聯的分析類復雜查詢、資料不經常更新的表,推薦使用列存表,

列存帶Delta表

對于列存表,如果業務是頻繁的小批量插入,那么將產生大量的小CU(單個CU里只有幾百條甚至幾條資料), 每個列的CU都是有壓縮代價的,小CU過多將嚴重影響列存表的查詢性能,

列存的Delta表就是針對這種場景實作的,讓小批量插入的資料先存盤到行存delta表,滿6w后由后臺autovacuum異步merge到主表CU,

需要注意的是列存帶Delta表只解決小批量入庫產生的小CU問題,不解決同一個CU上的并發更新問題

HStore表

前面提到,雖然列存老Delta表解決了小批量入庫產生的小CU問題,但是沒有解決同一個CU上的并發更新產生的鎖沖突問題,

而實時入庫的場景下,需要將insert+upsert+update操作實時并發入庫,資料來源于上游的其他資料庫或者應用,同時要求入庫后的資料要能及時查詢,且對于查詢的效率要求很高,

目前的列存表由于鎖沖突的原因無法支持并發upsert/update入庫,導致這些有需要的局點只能使用行存表,但是行存表因為格式的天然劣勢,在AP查詢場景下一方面性能較慢,另一方面由于壓縮差導致占用了大量的磁盤空間,對用戶產生額外成本,

GaussDB(DWS)中的HStore表, 在使用列存盤格式盡量降低磁盤占用的同時,支持高并發的更新操作入庫以及高性能的查詢效率,面向對于實時入庫和實時查詢有較強訴求的場景,同時擁有處理傳統TP場景的事務能力,

HStore表的示意圖如下:

GaussDB(DWS) 中幾種表型別的對比

HStore的Delta表

HStore表的實作主要依靠一張新設計的delta表以及記憶體并發控制機制,這里簡單講一下delta表的實作以及簡單的觀察delta表,

HStore的Delta表主要用于存放入庫產生的Insert/Delete/Update操作,小批量Insert的資料會先進入Delta形成一條型別是I(Insert)的記錄;洗掉會往Delta表插入一條型別是D(Delete)的記錄;更新操作(Upsert與Update)會拆分成Delete + Insert,會插入一條型別X(表示由更新產生的洗掉)的記錄以及一條型別I的記錄;
(型別是U(Update)的記錄由輕量化Update產生,不過當前輕量化更新默認關閉,所以不用管,)

可以看到,入庫時的Upsert/Update/Delete都會轉換成相應型別的記錄插入的HStore的Delta表中,再結合記憶體并發控制機制,就能保證同一個CU上更新于洗掉操作不會阻塞,同時,由于小批量的插入只會在Delta表上形成一條記錄,相比與列存老Delta的直接存盤資料,能減少IO占用,提高MERGE效率,

HStore的Delta表 與 列存老Delta表的對比

HStore的視圖與函式

當前HStore表提供了視圖,可以用來觀察Delta表的給型別元組數量以及Delta的膨脹情況,

select * from pgxc_get_hstore_delta_info('tableName');

同時也提供了函式可以對Delta表做輕量清理以及全量清理,

-- 輕量Merge滿6萬的I記錄以及CU上的洗掉資訊,持有四級鎖不阻塞業務增刪改查,但空間不會還給作業系統,
select hstore_light_merge('tableName'); 
-- 全量Merge所有記錄,然后truncate清空Delta表返還空間給系統,不過持有八級鎖會阻塞業務,
select hstore_full_merge('tableName');

這里做一個簡單的觀察實驗:

1.往HStore表上批量插入一百條資料,能看到生成了一條型別是I的記錄(n_i_tup 為1)

gaussdb=# create table data(a int primary key, b int);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "data_pkey" for table "data"
CREATE TABLE
gaussdb=# insert into data values(generate_series(1,100),1);
INSERT 0 100
gaussdb=# create table hs(a int primary key, b int)with(orientation=column, enable_hstore=on);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "hs_pkey" for table "hs"
CREATE TABLE
gaussdb=# insert into hs select * from data;
INSERT 0 100
gaussdb=# select * from pgxc_get_hstore_delta_info('hs'); --觀察hstore表的delta表上的各型別資料
 node_name | part_name | live_tup | n_i_type | n_d_type | n_x_type | n_u_type | n_m_type | data_size
-----------+---------------------+----------+----------+----------+----------+----------+----------+-----------
 dn_1      | non partition table | 1 | 1 | 0 | 0 | 0 | 0 | 8192
(1 row)

2.執行hstore_full_merge后能觀察到Delta表上沒有元組(live_tup為0),并且Delta表的空間大小data_size是0.

gaussdb=# select hstore_full_merge('hs');
 hstore_full_merge
-------------------
 1
(1 row)
gaussdb=# select * from pgxc_get_hstore_delta_info('hs'); --觀察hstore表的delta表上的各型別資料
 node_name | part_name | live_tup | n_i_type | n_d_type | n_x_type | n_u_type | n_m_type | data_size
-----------+---------------------+----------+----------+----------+----------+----------+----------+-----------
 dn_1      | non partition table | 0 | 0 | 0 | 0 | 0 | 0 | 0
(1 row)

3.執行洗掉,能觀察到Delta表上有一條型別是D的記錄(n_d_tup為1),

gaussdb=# delete hs where a = 1;
DELETE 1
gaussdb=# select * from pgxc_get_hstore_delta_info('hs'); --觀察hstore表的delta表上的各型別資料
 node_name | part_name | live_tup | n_i_type | n_d_type | n_x_type | n_u_type | n_m_type | data_size
-----------+---------------------+----------+----------+----------+----------+----------+----------+-----------
 dn_1      | non partition table | 1 | 0 | 1 | 0 | 0 | 0 | 8192
(1 row)

其它的操作這里不再一一嘗試,感興趣的讀者可以自己下來試一下,

HStore表的簡單使用實驗

準備作業

當需要使用HStore表時,需要同步修改以下幾個清理相關的引數默認值,否則會導致HStore表性能嚴重劣化,推薦的引數修改配置是:autovacuum_max_workers_hstore=3,autovacuum_max_workers=6,autovacuum=true,

并發更新實驗

在列存表上插入一批資料后,開啟兩個會話,

1.會話1洗掉某一條資料,然后不結束事務:

gaussdb=#  create table col(a int , b int)with(orientation=column);
CREATE TABLE
gaussdb=# insert into col select * from data;
INSERT 0 100
gaussdb=# begin;
BEGIN
gaussdb=# delete col where a = 1;
DELETE 1

2.會話2洗掉另一條資料,能看到會話2等待會話1,

gaussdb=# begin;
BEGIN
gaussdb=# delete col where a = 2;

會話1提交后會話2才能繼續執行,這就復現了列存的CU鎖問題:

3. 使用HStore表重復上面實驗,能觀察到會話2直接執行成功,不會鎖等待,

gaussdb=# begin;
BEGIN
gaussdb=# delete hs where a = 2;
DELETE 1

壓縮效率實驗

1.構建一張有三百萬資料的資料表data

gaussdb=# create table data( a int, b bigint, c varchar(10), d varchar(10));
CREATE TABLE
gaussdb=# insert into data values(generate_series(1,100),1,'asdfasdf','gergqer');
INSERT 0 100
gaussdb=# insert into data select * from data;
INSERT 0 100
gaussdb=# insert into data select * from data;
INSERT 0 200
---回圈插入,直到資料量達到三百萬
gaussdb=# insert into data select * from data;
INSERT 0 1638400
gaussdb=# select count(*) from data;
  count
---------
 3276800
(1 row)

2.批量匯入到行存表,觀察大小為223MB

gaussdb=# create table row (like data including all);
CREATE TABLE
gaussdb=# insert into row select * from data;
INSERT 0 3276800
gaussdb=#  select pg_size_pretty(pg_relation_size('row'));
 pg_size_pretty
----------------
 223 MB
(1 row)

3.批量匯入到列存表,觀察大小為3.5MB

gaussdb=# create table hs(a int, b bigint, c varchar(10),d varchar(10))with(orientation= column, enable_hstore=on);
CREATE TABLE
gaussdb=# insert into hs select * from data;
INSERT 0 3276800
gaussdb=#  select pg_size_pretty(pg_relation_size('hs'));
 pg_size_pretty
----------------
 3568 KB
(1 row)

4.總結

這個表結構比較簡單,資料也都是重復資料,所以HStore表的壓縮效果很好,一般情況下HStore表相比行存能有3-5倍的壓縮,

批量查詢性能實驗

還是使用上面建的表,這里簡單驗證一下批量查詢

1.查詢行存表的第四列,耗時在4s左右

gaussdb=# explain analyze select d from data;
explain analye                                                               QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------
  id |          operation           |        A-time | A-rows | E-rows | Peak Memory  | E-memory | A-width | E-width | E-costs
 ----+------------------------------+----------------------+---------+---------+--------------+----------+---------+---------+----------
 1 | ->  Streaming (type: GATHER) | 4337.881 | 3276800 | 3276800 | 32KB         | | | 8 | 61891.00
 2 | ->  Seq Scan on data | [1571.995, 1571.995] | 3276800 | 3276800 | [32KB, 32KB] | 1MB      | | 8 | 61266.00

2.查詢HStore表的第四列,耗時300毫秒左右

gaussdb=# explain analyze select d from hs;
                                                                    QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------
  id |               operation                |       A-time | A-rows | E-rows |  Peak Memory   | E-memory | A-width | E-width | E-costs
 ----+----------------------------------------+--------------------+---------+---------+----------------+----------+---------+---------+----------
 1 | -> Row Adapter                        | 335.280 | 3276800 | 3276800 | 24KB           | | | 8 | 15561.80
 2 | ->  Vector Streaming (type: GATHER) | 111.492 | 3276800 | 3276800 | 96KB           | | | 8 | 15561.80
 3 | -> CStore Scan on hs | [111.116, 111.116] | 3276800 | 3276800 | [254KB, 254KB] | 1MB      | | 8 | 14936.80

3.總結

這里只驗證了批量查詢場景,該場景下列存以及HStore表相比行存都有很好的查詢性能,但在索引點查詢場景下,列存是比不上行存的,這里不再做詳細對比,

HStore表注意事項

1.引數設定

HStore依賴后臺常駐執行緒對HStore表進行MERGE清理操作,才能保證查詢性能與壓縮效率,所以使用HStore表務必設定相關GUC,推薦的配置如下:

autovacuum_max_workers_hstore=3
autovacuum_max_workers=6
autovacuum=true

2.并發同一行:

當前HStore并發更新同一行仍然是不支持的,其中同一行上并發update/delete操作會先等鎖然后報錯,同一行上的并發upsert操作會先等鎖然后繼續執行,由于等待開銷也是會影響業務的入庫性能,甚至可能產生死鎖,所以需要在入庫時保證不會并發更新到同一行或者同一個key,

3.索引相關

索引會占用額外的空間,同時帶來的點查性能提升有限,所以HStore表只建議在需要做Upsert或者有點查(這里指唯一性與接近唯一的點查)的訴求下創建一個主鍵或者btree索引,

4.MERGE相關

由于HStore表依賴后臺autovacuum來將操作MERGE到主表,所以入庫速度不能超過MERGE速度,否則會導致delta表的膨脹,可以通過控制入庫的并發來控制入庫速度,同時由于Delta表本身的空間復用受oldestXmin的影響,如果有老事務存在可能會導致Delta空間復用不及時而產生膨脹,

5.UPSERT性能

HStore表雖然相比普通列存,并發upsert入庫性能得到了很大提升,但相比行存還是有差距,大概只有行存的1/3,所以在不追求壓縮率以及批量查詢性能、只追求單點查詢性能的場景下,還是推薦行存表入庫,

 

點擊關注,第一時間了解華為云新鮮技術~

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/555230.html

標籤:其他

上一篇:大檔案上傳功能在標簽服務的簡單應用和代碼實作

下一篇:返回列表

標籤雲
其他(161026) Python(38230) JavaScript(25496) Java(18240) C(15237) 區塊鏈(8270) C#(7972) AI(7469) 爪哇(7425) MySQL(7253) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4593) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2435) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) 功能(1967) HtmlCss(1966) Web開發(1951) C++(1940) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • HStore表全了解:實時入庫與高效查詢利器

    摘要:本文章將從使用者角度介紹HStore概念以及使用。 本文分享自華為云社區《GaussDB(DWS)HStore表講解》,作者:大威天龍:- 。 HStore表簡介 面對實時入庫和實時查詢要求越來越高的趨勢,已有的列存盤無法支持并發更新入庫,行存查詢性能無法做到實時回傳且空間壓縮表現不佳。Gau ......

    uj5u.com 2023-06-15 08:42:40 more
  • 大檔案上傳功能在標簽服務的簡單應用和代碼實作

    各位看官大家好,今天給大家分享的又是一篇實戰文章,希望大家能夠喜歡。 目前「[袋鼠云客戶資料洞察平臺](https://www.dtstack.com/easydigit/userinsight?src=https://www.cnblogs.com/DTinsight/archive/2023/06/14/szsm)」標簽服務的群組按種類劃分,可以分為三大類,分別是實時群組、[動態群組](https: ......

    uj5u.com 2023-06-15 08:42:12 more
  • 如何成功實施一個資料治理專案?實施步驟有哪些?

    企業數字化轉型以資料為中心,通過資料驅動業務發展、管理協同和運營。因此,數字化轉型關鍵在于資料,[資料治理](https://www.dtstack.com/resources/1001?src=https://www.cnblogs.com/DTinsight/archive/2023/06/14/szsm)則需先行。從而更好激發資料生產要素潛能,實作業務資料化、資料價值化,助力企業數字化轉型。 ## ......

    uj5u.com 2023-06-15 08:41:46 more
  • MySQL中都有哪些鎖?

    # MySQL中都有哪些鎖 ## 為什么需要鎖 在計算機系統中,鎖(`Lock`)是一種同步機制,用于控制對共享資源的訪問。它確保在任何給定時間內只有一個執行緒能夠訪問受保護的共享資源,從而避免了由并發訪問導致的資料競爭和不一致問題。 同樣,在資料庫系統中,鎖也扮演著重要角色,是其與檔案系統不同的關鍵 ......

    uj5u.com 2023-06-15 08:41:31 more
  • 2種GaussDB(DWS)查看作業運行資訊方式

    摘要:提供以作業基本單位的作業統計視圖pgxc_session_wlmstat,便于用戶觀察運行作業和排隊作業資訊。 本文分享自華為云社區《GaussDB(DWS)如何查看作業運行資訊》,作者:幕后小黑爪。 用戶反饋,出現連接數告警,作業并發數高,超過資源池限制,與實際配置不符。經過了解,用戶使用p ......

    uj5u.com 2023-06-15 08:40:51 more
  • 【后端面經-資料庫】MySQL的事務隔離級別簡介

    [TOC](【后端面經-資料庫】MySQL的事務隔離級別簡介) ## 0. 事務的概念 事務指的是一連串的集中操作指令,一個事務的執行必須執行完所有的動作才能算作執行結束。事務具有四個特點,簡記作`ACID`: - `A`-Atomicity: 原子性,事務的執行必須保證所有的動作都執行完畢; - ......

    uj5u.com 2023-06-15 08:39:46 more
  • MySQL中都有哪些鎖?

    # MySQL中都有哪些鎖 ## 為什么需要鎖 在計算機系統中,鎖(`Lock`)是一種同步機制,用于控制對共享資源的訪問。它確保在任何給定時間內只有一個執行緒能夠訪問受保護的共享資源,從而避免了由并發訪問導致的資料競爭和不一致問題。 同樣,在資料庫系統中,鎖也扮演著重要角色,是其與檔案系統不同的關鍵 ......

    uj5u.com 2023-06-15 08:39:36 more
  • Hive常見時間日期函式的使用與問題整理

    hive本身提供的時間函式已經很豐富了,基本上能滿足我們所有的需求,一些特殊需求也可以通過增加一些數學邏輯實作出來。 ......

    uj5u.com 2023-06-15 08:39:20 more
  • HStore表全了解:實時入庫與高效查詢利器

    摘要:本文章將從使用者角度介紹HStore概念以及使用。 本文分享自華為云社區《GaussDB(DWS)HStore表講解》,作者:大威天龍:- 。 HStore表簡介 面對實時入庫和實時查詢要求越來越高的趨勢,已有的列存盤無法支持并發更新入庫,行存查詢性能無法做到實時回傳且空間壓縮表現不佳。Gau ......

    uj5u.com 2023-06-15 08:39:09 more
  • 大檔案上傳功能在標簽服務的簡單應用和代碼實作

    各位看官大家好,今天給大家分享的又是一篇實戰文章,希望大家能夠喜歡。 目前「[袋鼠云客戶資料洞察平臺](https://www.dtstack.com/easydigit/userinsight?src=https://www.cnblogs.com/DTinsight/p/szsm)」標簽服務的群組按種類劃分,可以分為三大類,分別是實時群組、[動態群組](https: ......

    uj5u.com 2023-06-15 08:38:32 more