Greenplum 模糊查询 实践

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

标签

PostgreSQL , Greenplum , orafunc , 阿里云HybridDB for PostgreSQL , reverse , like , 模糊查询


背景

文本搜索的需求分为:

1、全匹配,如:

select * from table where column = 'xxxx';  

2、后模糊,如:

select * from table where column like 'xxxx%';  

3、前模糊,如:

select * from table where column like '%xxxx';  

4、前后模糊,如:

select * from table where column like '%xxxx%';  

《中文模糊查询性能优化 by PostgreSQL trgm》

5、正则,如:

select * from table where column ~ 'abc[he|ww]{1,3}.?[\d]*';  

《中文模糊查询性能优化 by PostgreSQL trgm》

6、相似,如:

select * from table where similar(column, 'postgresql');   

《中文模糊查询性能优化 by PostgreSQL trgm》

7、短文向量相似,如:

select * from table where column % array['x1','x2',''''];  

《海量数据,海明(simhash)距离高效检索(smlar) - 阿里云RDS PosgreSQL最佳实践》

8、全文检索,如:

select * from table where column @@ to_tsquery('zhongguo & hello');  

《PostgreSQL 行级 全文检索》

9、特征匹配搜索,如:

select * from table where column op array['',......];  -- 涉及到文本的关系、知识图谱、机器学习的领域  

以及忽略大小写的搜索。。。。。

其中模糊查询最为常见。下面分享一下在Greenplum数据库中,如何更好的实现前、后模糊搜索。

创建支持反转查询的插件

create extension orafunc;  

构建测试数据

1、建表

postgres=> create table test1(id int, info text);  
NOTICE:  Table doesn't have 'DISTRIBUTED BY' clause -- Using column named 'id' 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  

2、写入测试数据

postgres=> insert into test1 select id, md5(random()::text) from generate_series(1,10000000) t(id);  
INSERT 0 10000000  

3、创建正向搜索和反向搜索的索引

postgres=> create index idx1 on test1(info);  
CREATE INDEX  
  
create index idx2 on test1(reverse(info));  

4、数据样本

postgres=> select * from test1 limit 10;  
 id |               info                 
----+----------------------------------  
  3 | ab66abe2d548eb1f21cdb410e27c43a6  
  7 | b4717483def19ec9426548a452b190e0  
 11 | 1bf7dfa6205b19337c486b8a3ac1981f  
 15 | 68bc077b0283e29db0516e90c7a9ae49  
 19 | 6171f25d1b3306f794fa508ae72f2f2f  
 23 | 7f8e50c0a2a1114816afd93f36585715  
 27 | 0d1b246c9b35b199512c500617f011b8  
 31 | 359a18646f95daa28ae8070a73b9b2bf  
 35 | f0786c5efdc526a3aab79479e5c65e83  
 39 | e6fac18e0a464487ef72a55cbbce3ca4  
(10 rows)  

5、创建模糊查询依赖的函数(求前缀或后缀的下一个边界值)。

postgres=> create or replace function next_str(text) returns text as $$    
  select lpad($1, length($1)-1) || chr(ascii(substring($1, length($1), 1))+1);   
$$ language sql strict immutable;  
CREATE FUNCTION  

6、后模糊查询(提供前缀)。

postgres=> explain analyze select * from test1 where info >= 'ab66abe' and info < next_str('ab66abe');  
                                                 QUERY PLAN                                                   
------------------------------------------------------------------------------------------------------------  
 Gather Motion 4:1  (slice1; segments: 4)  (cost=0.00..2085583.56 rows=98944 width=37)  
   Rows out:  1 rows at destination with 1.721 ms to first row, 1.842 ms to end, start offset by 0.214 ms.  
   ->  Index Scan using idx1 on test1  (cost=0.00..2085583.56 rows=24736 width=37)  
         Index Cond: info >= 'ab66abe'::text AND info < 'ab66abf'::text  
         Rows out:  1 rows (seg0) with 0.034 ms to first row, 0.036 ms to end, start offset by 1.971 ms.  
 Slice statistics:  
   (slice0)    Executor memory: 159K bytes.  
   (slice1)    Executor memory: 145K bytes avg x 4 workers, 145K bytes max (seg0).  
 Statement statistics:  
   Memory used: 2047000K bytes  
 Settings:  effective_cache_size=8GB; enable_bitmapscan=off; enable_seqscan=off; gp_statistics_use_fkeys=on  
 Optimizer status: legacy query optimizer  
 Total runtime: 2.182 ms  
(13 rows)  

7、前模糊查询(提供后缀)。

postgres=> explain analyze select * from test1 where reverse(info) >= 'e4495c' and reverse(info) < next_str('e4495c');  
                                                 QUERY PLAN                                                   
------------------------------------------------------------------------------------------------------------  
 Gather Motion 4:1  (slice1; segments: 4)  (cost=0.01..2085704.88 rows=100010 width=37)  
   Rows out:  1 rows at destination with 1.694 ms to first row, 1.768 ms to end, start offset by 0.224 ms.  
   ->  Index Scan using idx2 on test1  (cost=0.01..2085704.88 rows=25003 width=37)  
         Index Cond: reverse(info) >= 'e4495c'::text AND reverse(info) < 'e4495d'::text  
         Rows out:  1 rows (seg1) with 0.034 ms to first row, 0.037 ms to end, start offset by 1.844 ms.  
 Slice statistics:  
   (slice0)    Executor memory: 159K bytes.  
   (slice1)    Executor memory: 151K bytes avg x 4 workers, 151K bytes max (seg0).  
 Statement statistics:  
   Memory used: 2047000K bytes  
 Settings:  effective_cache_size=8GB; enable_bitmapscan=off; enable_seqscan=off; gp_statistics_use_fkeys=on  
 Optimizer status: legacy query optimizer  
 Total runtime: 2.220 ms  
(13 rows)  

《PostgreSQL 生成随机身份证ID》

使用这种方法,生成10亿身份证信息,前后模糊查询,性能杠杠的。5毫秒内返回。

建议

建议,这类查询还是属于OLTP的范畴,如果数据量在单实例可以存下的范围内,建议还是使用PostgreSQL。例如阿里云PolarDB for PostgreSQL,可以COVER 100TB的容量规格,同时支持一写多读的架构。

同时,PostgreSQL还可以通过pg_trgm与GIN索引支持全模糊、正则、字符串相似、短文特征向量相似的搜索,比Greenplum在本case支持的范畴更加广泛。

参考

《Greenplum 最佳实践 - 如何支持反转索引》

《PostgreSQL 模糊查询最佳实践》

《PostgreSQL 全表 全字段 模糊查询的毫秒级高效实现 - 搜索引擎颤抖了》

《从难缠的模糊查询聊开 - PostgreSQL独门绝招之一 GIN , GiST , SP-GiST , RUM 索引原理与技术背景》

《中文模糊查询性能优化 by PostgreSQL trgm》

《PostgreSQL 百亿数据 秒级响应 正则及模糊查询》

《聊一聊双十一背后的技术 - 毫秒分词算啥, 试试正则和相似度》

《聊一聊双十一背后的技术 - 分词和搜索》

《PostgreSQL 如何高效解决 按任意字段分词检索的问题 - case 1》

《如何加快PostgreSQL结巴分词加载速度》

《PostgreSQL 结巴分词》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
Web App开发 关系型数据库 数据库
用PostgreSQL 做实时高效 搜索引擎 - 全文检索、模糊查询、正则查询、相似查询、ADHOC查询
用PostgreSQL 做实时高效 搜索引擎 - 全文检索、模糊查询、正则查询、相似查询、ADHOC查询作者digoal 日期2017-12-05 标签PostgreSQL , 搜索引擎 , GIN , ranking , high light , 全文检索 , 模糊查询 , 正则查询 , 相似查询 , ADHOC查询 背景字符串搜索是非常常见的业务需求,它包括: 1、前缀+模糊查询。
10310 1
|
7月前
|
关系型数据库 PostgreSQL 索引
PostgreSQL技术大讲堂 - 第30讲:多表连接方式
从零开始学PostgreSQL技术大讲堂 - 第30讲:多表连接方式
264 2
|
3天前
|
存储 关系型数据库 分布式数据库
PolarDB 开源版通过 pg_trgm GIN 索引实现高效率 `like '%xxx%'` 模糊查询
背景PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的 价值产出, 将数据变成生产力.本文将介绍PolarDB 开源版通过 pg_trgm GIN 索引实现高效率lik...
|
SQL 存储 关系型数据库
PostgreSQL表的查询(难度适中)
PostgreSQL表的查询(难度适中)
197 0
PostgreSQL表的查询(难度适中)
|
关系型数据库 数据挖掘 数据库
PostgreSQL 模糊查询最佳实践 - (含单字、双字、多字模糊查询方法)
PostgreSQL 模糊查询最佳实践 - (含单字、双字、多字模糊查询方法)https://github.com/digoal/blog/blob/master/201704/20170426_01.md
13646 0
|
SQL 自然语言处理 搜索推荐
【重新发现PostgreSQL之美】- 16 like '%西出函谷关%' 模糊查询
大家好,这里是重新发现PostgreSQL之美 - 16 like '%西出函谷关%' 模糊查询
|
SQL 关系型数据库 PostgreSQL
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 12 章 全文搜索_12.2. 表和索引
12.2. 表和索引 12.2.1. 搜索一个表 12.2.2. 创建索引 在前一节中的例子演示了使用简单常数字符串进行全文匹配。本节展示如何搜索表数据,以及可选择地使用索引。 12.2.1. 搜索一个表 可以在没有一个索引的情况下做一次全文搜索。
1099 0
|
SQL 关系型数据库 PostgreSQL
PostgreSQL 10.1 手册_部分 II. SQL 语言_第 7 章 查询_7.4. 组合查询
7.4. 组合查询 两个查询的结果可以用集合操作并、交、差进行组合。语法是 query1 UNION [ALL] query2 query1 INTERSECT [ALL] query2 query1 EXCEPT [ALL] query2 query1和query2都是可以使用以上所有特性的查询。
1100 0
|
Web App开发 SQL 关系型数据库
|
SQL 关系型数据库 PostgreSQL