大數據“復活”記
1107
2025-03-31
GaussDB(DWS)實踐系列-RoaringBitmap替換方案
Roaring Bitmap(下文簡稱RBM)是一種高效優秀的位圖壓縮算法,通過位圖能夠快速定位一個數值是否在存在,適合大數據查詢和關聯計算,例如標簽篩選、用戶畫像、去重等場景,目前也被廣泛應用在部分大數據平臺上。當前GaussDB(DWS)不支持,針對該場景可參考本文方法實現RoaringBitmap的場景替換,結合客戶實際業務場景測試,性能也并不比RoaringBitmap差。
一、??? RBM場景樣例
原表如下,需要查詢滿足tag_code:tag_value 的值為TAC004:0.00 and TAC005:t and TAC006:abc TAC005:2021/09/08 and .....的god_id。
如果使用Roaring Bitmap插件實現,原表跑批加工為一張有bitmap字段類型的表(字段 tag_code,tag_value,user_bits(二進制類型)),通過Roaring bitmap的函數去查該表。
二、??? 替待方案
(一) 概念介紹
GaussDB(DWS)使用string_agg函數 + 全文檢索替代 RoaringBitmap。
(1)String_agg的功能是將輸入值連接成為一個字符串,用分隔符分開。返回類型和參數數據類型相同。例如SELECT string_agg(sr_item_sk, ',') FROM tpcds.store_returns where sr_item_sk < 3;
(2)全文檢索可以對文檔進行預處理,并且可以使后續的搜索更快速。數據類型tsvector用于存儲預處理文檔,tsquery用于存儲查詢條件。全文檢索基于匹配算子@@,當一個tsvector(document)匹配到一個tsquery(query)時,則返回true。其中,tsvector(document)和tsquery(query)兩種數據類型可以任意排序。例如:
SELECT 'a fat cat sat on a mat and ate a fat rat'::tsvector @@ 'cat & rat'::tsquery AS RESULT;
查詢結果:
SELECT 'fat & cow'::tsquery @@ 'a fat cat sat on a mat and ate a fat rat'::tsvector AS RESULT;
查詢結果:
tsvector類型表示為文本搜索優化的文件格式,tsquery類型表示文本查詢。tsvector類型表示一個檢索單元,通常是一個數據庫表中一行的文本字段或者這些字段的組合,tsvector類型的值是一個標準詞位的有序列表,標準詞位就是把同一個詞的變型體都標準化相同的,在輸入的同時會自動排序和消除重復。to_tsvector函數通常用于解析和標準化文檔字符串。
tsquery類型表示一個檢索條件,存儲用于檢索的詞匯,并且使用布爾操作符&(AND),|(OR)和!(NOT)來組合他們,括號用來強調操作符的分組。to_tsquery函數及plainto_tsquery函數會將單詞轉換為tsquery類型前進行規范化處理。
(二) 實施方案
1.?????? 創建目標表
其中數據類型tsvector用于存儲預處理文檔。
CREATE? TABLE test_table (
god_id character varying ,
codevalue text,
textsearchable_index_col tsvector
) WITH (orientation=row)
DISTRIBUTE BY HASH(god_id);
CREATE INDEX ON test_table USING gin (textsearchable_index_col);
備注:相比于一個表達式索引,單獨列(textsearchable_index_col)方法的一個優勢是它沒有必要在查詢時明確指定分詞器以便能使用索引,另一個優勢是搜索比較快速,因為它沒有必要重新利用to_tsvector調用來驗證索引匹配。表達式索引方法更容易建立,且它需要較少的磁盤空間,因為tsvector形式沒有明確存儲。
2.?????? 原表加工
原表加工后插入到目標表。
備注:tag_code||'-'||tag_value可以把字符'-'換成別的字符,但不能換成冒號':',冒號是tsvector專用的字符。
insert into test_table? (
select god_id,codevalue,codevalue::tsvector from
(
select god_id ,string_agg(tag_code||'-'||tag_value,' ') as codevalue from user_profile
group by god_id
));
3.?????? 查詢語句
查詢1個標簽
SELECT god_id, code_value FROM test_table WHERE textsearchable_index_col @@ 'TAC004-0.00'? limit 200;
查詢結果:
select count(*) from (SELECT god_id FROM test_table WHERE textsearchable_index_col @@ 'TAC004-0.00')
查詢結果:
查詢3個標簽
SELECT god_id, code_value FROM test_table WHERE textsearchable_index_col @@ 'TAC004-0.00 & TAC004-abc'? limit 200;
查詢結果:
SELECT god_id, code_value FROM test_table WHERE textsearchable_index_col @@ 'TAC004-0.00 | TAC005-abc'? limit 200;
查詢結果:
select count(*) from (SELECT god_id, code_value FROM test_table WHERE textsearchable_index_col @@ 'TAC004-0.00 | TAC005-abc');
查詢結果:
注意:
(1)對于to_tsvector('str1') @@ to_tsquery('str2'),to_tsvector會按照所有符號去分詞,例如:
SELECT to_tsvector('fat tac01-01 2020-09-08') @@ to_tsquery('tac01-01') AS RESULT;
查詢結果:
可以修改為使用 ' str1'::tsvector @@ ' str2'
SELECT 'fat tac01-01 2020-09-08'::tsvector @@ 'tac01-01' AS RESULT;
查詢結果:
(2)因為$$在實際操作中使用有問題,需要進行語法替換,例如:
select $$a001 c1.09 d0.08 e01:20 TAC001:21 2021-09-08$$::tsvector;
需要替換成:
select 'a001 c1.09 d0.08 e01:20 TAC001:21 2021-09-08'::tsvector;
EI企業智能 Gauss AP 數據倉庫服務 GaussDB(DWS) 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。