Greenplum 2000亿 近似度查询 性能 以及注意事项

简介:

greenplum和PostgreSQL一样,都是通过pg_trgm来支持近似度查询的。
原理是将字符串前加2空格,末尾加1空格,然后按照3个连续的字符串为一组,打散成多个字符串。然后计算字符串的重复度来计算两个字符串的相似度。
计算重复度时,需要进行去重复的操作。
例如:

postgres=# select similarity('abcde','abcabc');  
 similarity   
------------  
   0.333333  
(1 row)  
Time: 0.413 ms  

以上两个字符串被拆分成如下token(以下-代表空格)
--a, -ab, abc, bcd, cde, de-
--a, -ab, abc, bca, cab, abc, bc-
两者token去重后的集合为
--a, -ab, abc, bcd, cde, de-, bca, cab, bc-
重复的token为
--a, -ab, abc
所以abcde 和 abcabc 的近似度=3/9=0.333333

greenplum安装pg_trgm也很简单。

cd gpsrc/contrib/pg_trgm/  

现在有个bug需要手工fix一下

vi trgm.h  
#define TRGMINT(a) ( (*(((char*)(a))+2)<<16)+(*(((char*)(a))+1)<<8)+*(((char*)(a))+0) )  
  
make && make install  
  
gpscp -f ./host /home/digoal/gphome/lib/postgresql/pg_trgm.so =:/home/digoal/gphome/lib/postgresql/pg_trgm.so  
gpscp -f ./host /home/digoal/gphome/share/postgresql/contrib/uninstall_pg_trgm.sql =:/home/digoal/gphome/share/postgresql/contrib/uninstall_pg_trgm.sql  
gpscp -f ./host /home/digoal/gphome/share/postgresql/contrib/pg_trgm.sql =:/home/digoal/gphome/share/postgresql/contrib/pg_trgm.sql  
  
psql -f /home/digoal/gphome/share/postgresql/contrib/pg_trgm.sql  

测试

postgres=# create table t(info text);  
NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'info' as the Greenplum Database data distribution key for this table.  
HINT:  The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew.  
CREATE TABLE  
postgres=# insert into t select md5(random()::text) from generate_series(1,100);  
INSERT 0 100  
postgres=# select * from t limit 10;  
               info                 
----------------------------------  
 2d33d6379b85eb7a3c4090dce7a0ebe2  
 75b4be956b90f8a8c528f847eddd34fe  
 ae7f1bb726486fba174cfc27a90ea080  
 b714894688f9ef9272c61d09efebb361  
 d8774ded2bad3c4aafb85cc98fea7d06  
 afdc717a7e4c73e22a497db9c2812bfa  
 eda761ac73f659072ae2084268d5f2fe  
 e2660e7b3a9a7824611c4af93bc2c4d9  
 8659bdb87b3f5d3e6d7f269233e12d4b  
 fd28ec09a46d2f35b3b3461ab48d1998  
(10 rows)  

当前的近似度阈值为0.3,当两个字符串的近似度小于0.3时,返回false。

postgres=# select show_limit();  
 show_limit   
------------  
        0.3  
(1 row)  
  
postgres=# select '2d33d6379b85eb7a3c4090dce7a0ebe2' % 'eb7a3c409';  
 ?column?   
----------  
 f  
(1 row)  
  
postgres=# select * from t where info % 'eb7a3c409';  
 info   
------  
(0 rows)  

使用set_limit可以设置近似度阈值

postgres=# select set_limit(0.1);  
 set_limit   
-----------  
       0.1  
(1 row)  
  
postgres=# select '2d33d6379b85eb7a3c4090dce7a0ebe2' % 'eb7a3c409';  
 ?column?   
----------  
 t  
(1 row)  
  
postgres=# select * from t where info % 'eb7a3c409';  
 info   
------  
(0 rows)  

为什么查询表的记录时没有起作用呢?
原因是set_limit()函数没有在segment上执行,它们还是0.3:

postgres=# select show_limit() from gp_dist_random('gp_id');  
 show_limit   
------------  
        0.3  
        0.3  
        0.3  
        0.3  
    ......

通过gp_dist_random强制在segment执行,

postgres=# select set_limit(0.1) from gp_dist_random('gp_id');  
 set_limit   
-----------  
       0.1  
       0.1  
       0.1  
       ......
  
postgres=# select * from t where info % 'eb7a3c409';  
               info                 
----------------------------------  
 2d33d6379b85eb7a3c4090dce7a0ebe2  
(1 row)  

由于GP有会话缓存,释放后,又需要重新和segment建立连接,这时又回到0.3了。

postgres=# select * from t where info % 'eb7a3c409';  
 info   
------  
(0 rows)  
postgres=# select show_limit() from gp_dist_random('gp_id');  
 show_limit   
------------  
        0.3  
        0.3  
        0.3  
        0.3  
    ......

以上就是greenplum的近似度查询的用法。
还支持索引哦 :
索引不受set_limit的影响,也就是说索引中不存储固定的limit值,是随时可调整的。

create index idx on t using gist (info gist_trgm_ops);

目前还不支持GIN,因为GP的GIN索引在AO表的使用方面有问题,存在同步的问题,可能导致数据不一致。

src/backend/commands/indexcmds.c
..

        /* MPP-9329: disable creation of GIN indexes */
        if (accessMethodId == GIN_AM_OID)
                ereport(ERROR,
                                (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                 errmsg("GIN indexes are not supported")));
..

预知2000亿的近似度查询性能,明天放出。

postgres=# select count(distinct info),count(*) from t_regexp_100billion ;  
   count    |    count       
------------+--------------  
 2147475713 | 212600000000  
(1 row)  
  
postgres=# explain select ctid,* from t_regexp_100billion where info >='3347597ec8' and info<'3347597ec9' and info like '3347597ec8%' limit 5;  
                                                                      QUERY PLAN                                                                         
-------------------------------------------------------------------------------------------------------------------------------------------------------  
 Limit  (cost=0.00..2479.65 rows=5 width=19)  
   ->  Gather Motion 240:1  (slice1; segments: 240)  (cost=0.00..2479.65 rows=5 width=19)  
         ->  Limit  (cost=0.00..2479.55 rows=1 width=19)  
               ->  Index Scan using idx_1 on t_regexp_100billion  (cost=0.00..396651039.36 rows=3333 width=19)  
                     Index Cond: info >= '3347597ec8'::text AND info < '3347597ec9'::text AND info >= '3347597ec8'::text AND info < '3347597ec9'::text  
                     Filter: info ~~ '3347597ec8%'::text  
 Settings:  enable_seqscan=off  
(7 rows)  
Time: 55.146 ms  
  
postgres=# select ctid,* from t_regexp_100billion where info >='3347597ec8' and info<'3347597ec9' and info like '3347597ec8%' limit 5;  
     ctid     |     info       
--------------+--------------  
 (663830,524) | 3347597ec812  
 (704622,147) | 3347597ec812  
 (682224,472) | 3347597ec812  
 (644991,150) | 3347597ec812  
 (667081,662) | 3347597ec812  
(5 rows)  
Time: 57.635 ms  
  
postgres=# explain select ctid,* from t_regexp_100billion where info >='3347597' and info<'3347598' and reverse(info)>='218c' and reverse(info)<'218d' and info like '3347597%c812' limit 5;  
                                                   QUERY PLAN                                                      
-----------------------------------------------------------------------------------------------------------------  
 Limit  (cost=0.01..304985.33 rows=5 width=19)  
   ->  Gather Motion 240:1  (slice1; segments: 240)  (cost=0.01..304985.33 rows=5 width=19)  
         ->  Limit  (cost=0.01..304985.23 rows=1 width=19)  
               ->  Index Scan using idx_2 on t_regexp_100billion  (cost=0.01..99181639.41 rows=7 width=19)  
                     Index Cond: reverse(info) >= '218c'::text AND reverse(info) < '218d'::text  
                     Filter: info >= '3347597'::text AND info < '3347598'::text AND info ~~ '3347597%c812'::text  
 Settings:  enable_seqscan=off  
(7 rows)  
Time: 55.338 ms  
  
postgres=# select ctid,* from t_regexp_100billion where info >='3347597' and info<'3347598' and reverse(info)>='218c' and reverse(info)<'218d' and info like '3347597%c812' limit 5;  
     ctid     |     info       
--------------+--------------  
 (704622,147) | 3347597ec812  
 (731733,400) | 3347597ec812  
 (774593,650) | 3347597ec812  
 (739526,433) | 3347597ec812  
 (779749,565) | 3347597ec812  
(5 rows)  
Time: 104.845 ms  
  
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
Linux API 内存技术
Linux Kernel中AEP的现状和发展
AEP简介AEP是Intel推出的一种新型的非易失Optane Memory设备,又被称作Apache Pass,所以一般习惯称作AEP。在这之前也有类似的设备称作NVDIMM或PMEM,目前Linux创建的AEP设备节点也是叫做pmem(如/dev/pmem0),所以本文中NVDIMM或PMEM都指AEP。
5261 0
【CentOS8】 本地yum源配置
centos8系统的本地yum源配置稍稍有些不同
3294 0
【CentOS8】 本地yum源配置
|
8月前
|
存储 人工智能 测试技术
基于 VectorDBBench 的性能评测与架构解析:Lindorm 向量引擎的优化实践
阿里云Lindorm向量检索服务重磅升级,依托CBO/RBO混合优化器与自适应混合索引,实测QPS达5.6万(百万级)、2.4万+(千万级),P99延迟低至2ms,融合检索性能行业领先,全面支撑AI时代高并发、低延迟、强一致的生产级向量应用。
1081 4
|
9月前
|
SQL 安全 数据库
GoWind Admin|风行 — 开箱即用的企业级全栈中后台框架:数据权限体系设计与实现
GoWind Admin(风行)是开箱即用的企业级全栈中后台框架,内置五层数据权限体系:租户隔离、业务单元、行级、列级、操作/状态级,支持多租户、ABAC动态策略与非侵入式DataScope引擎,实现安全合规、灵活可扩展的权限管理。(239字)
1536 2
|
12月前
|
人工智能 前端开发 JavaScript
Gemini CLI 架构学习指南
本指南深入解析开源终端AI助手Gemini CLI的架构设计,涵盖项目结构、核心流程与技术栈(TypeScript/React+Ink/Node.js),并提供从环境搭建到贡献代码的四阶段学习路径,助力开发者掌握AI编程工具开发精髓。
1640 3
|
数据采集 Web App开发 JavaScript
Jsoup 爬虫:轻松搞定动态加载网页内容
Jsoup 爬虫:轻松搞定动态加载网页内容
|
SQL 人工智能 数据挖掘
quickbi使用总结以及问题反馈
本文总结了使用QuickBI高级版及电子表格的功能体验与改进建议。内容涵盖具体报表使用(如趋势分析表、多维趋势表)、函数及其他模块(如LOD函数、自助取数)、AI智能问数模块以及数据集使用的优缺点。指出趋势分析表在复合指标处理上的不足,多维趋势表对比周期限制,以及1万条明细数据限制对年同比的影响等问题。同时提出未来期望,希望建立结合企业知识库的大模型,优化数据分析与建议能力。
1356 46
|
存储 SQL 关系型数据库
数据仓库、数据湖、流批一体,终于有大神讲清楚了!
数据仓库,数据湖,包括Flink社区提的流批一体,它们到底能解决什么问题?今天将由阿里云研究员从解决业务问题出发,将问题抽丝剥茧,从技术维度娓娓道来:为什么你需要数据湖或者数据仓库解决方案?它的核心难点与核心问题在哪?如果想稳定落地,系统设计该怎么做?
5762 0
|
人工智能 自然语言处理 前端开发
OpenAI 12天发布会全解析 | AI大咖说
OpenAI近日宣布将在12个工作日内每天进行一场直播,展示一系列新产品和样品。首日推出GPT-o1正式版,性能大幅提升;次日展示Reinforcement Fine-Tuning技术,提高模型决策质量;第三天推出Sora,实现高质量视频生成;第四天加强Canvas,提升多模态创作效率;第五天发布ChatGPT扩展功能,增强灵活性;第六天推出ChatGPT Vision,实现多模态互动;第七天推出ChatGPT Projects,优化项目管理。这些新技术正改变我们的生活和工作方式。
2380 9
|
算法 物联网 异构计算
基于FPGA的4FSK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR
本文介绍了基于FPGA的4FSK调制解调系统的Verilog实现,包括高斯信道模块和误码率统计模块,支持不同SNR设置。系统在Vivado 2019.2上开发,展示了在不同SNR条件下的仿真结果。4FSK调制通过将输入数据转换为四个不同频率的信号来提高频带利用率和抗干扰能力,适用于无线通信和数据传输领域。文中还提供了核心Verilog代码,详细描述了调制、加噪声、解调及误码率计算的过程。
701 11

热门文章

最新文章