GaussDB(DWS)实践系列-RoaringBitmap替换方案

举报
四叶草 发表于 2021/08/30 15:34:27 2021/08/30
【摘要】 Roaring Bitmap(下文简称RBM)是一种高效优秀的位图压缩算法,通过位图能够快速定位一个数值是否在存在,适合大数据查询和关联计算,例如标签筛选、用户画像、去重等场景,目前也被广泛应用在部分大数据平台上。当前GaussDB(DWS)不支持,针对该场景可参考本文方法实现RoaringBitmap的场景替换,结合客户实际业务场景测试,性能也并不比RoaringBitmap差。

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_codetag_valueuser_bits(二进制类型)),通过Roaring bitmap的函数去查该表。

二、    替待方案

(一) 概念介绍

GaussDB(DWS)使用string_agg函数 + 全文检索替代 RoaringBitmap

1String_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;

 

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200