多模融合查询: 文本(分词匹配、模糊匹配、字面相似、rank算法、rank排序) + AI(语义向量相似、其他相似) + 空间(范围、距离排序) + 数组标签(包含、相交、不包含、相似性) + 标量过滤(范围、等值、不等) + 图
digoal
2024-01-31
PostgreSQL , PolarDB , DuckDB , 多模 , 超融合 , 多重过滤 , 多重召回 , 多重排序 , 文本(分词匹配、模糊匹配、字面相似、rank算法、rank排序) , AI向量(语义向量相似、其他相似) , 空间(范围、距离排序) , 数组标签(包含、相交、不包含、相似性) , 标量过滤(范围、等值、不等) , 图
从数据中提取关心的数据, 是发挥数据价值的必要手段, 数据提取就是过滤不需要的, 留下需要的. 看似简单, 实际上很难, 特别是当你关心效率时.
为什么效率问题是世纪难题呢? 因为
- 1、过滤的种类非常多, 不同的过滤种类要使用不同的索引接口来进行加速, 没有一种索引能支持所有的查询.
- 2、过滤可以用索引, 排序却不行, 需要显示的sort, 如果结果集比较大需要limit/分页返回时, 显示sort带来的cpu消耗就会激增, 加点并发估计cpu消耗就爆仓了.
下面介绍一下常见的过滤种类, 以及对应的插件和索引.
1、文本(分词匹配、模糊匹配、字面相似、rank算法、rank排序) +
1.1、全文检索: 分词匹配、rank算法、rank排序
中文分词插件
- pg_jieba
- zhparser
ts rank算法
- 词频加权 (内置)
- 词出现的位置加权(标题、作者、摘要、内容) (内置)
- tf-idf 加权 (pg_bm25插件/smlar插件. 支持更多高级加权, 类似ES的算法. 这家公司的目标应该是基于PG做比较强大的计算+搜索引擎. )
索引
- gin (rank sort需要实时计算, 无法通过gin索引支持)
- rum (同时支持全文检索+rank排序)
关于全文检索还可以参考
- https://xata.io/blog/postgres-full-text-search-engine
- https://xata.io/blog/postgres-full-text-search-postgres-vs-elasticsearch
1.2、字符串搜索: 模糊匹配、等值匹配等
插件
- pg_trgm, 模糊搜索 《PostgreSQL 模糊查询最佳实践 - (含单字、双字、多字模糊查询方法)》
- groonga, 支持wchar的任意模糊搜索 《PostgreSQL 模糊查询增强插件pgroonga , pgbigm (含单字、双字、多字、多字节字符) - 支持JSON模糊查询等》
- pg_bigm, 增强pg_trgm模糊搜索
索引
- gin
2、AI(语义向量相似、其他相似) +
2.1、基于向量的相似搜索
插件:
- pgvector
索引
- hnsw
- ivfflat
3、空间(范围、距离排序) +
3.1、二维、三维空间搜索, 轨迹匹配, 按地域圈选, 按距离排序, 点云存储和搜索等
插件
- postgis
- pgrouting
- pgpointcloud
索引
- gist
- sp-gist
- brin
4、数组标签(包含、相交、不包含、相似性) +
4.1、基于数组标签的圈选, 例如包含、相交、不包含
- 《HTAP数据库 PostgreSQL 场景与性能测试之 19 - (OLAP) 用户画像圈人场景 - 数组相交查询与聚合》
- 《HTAP数据库 PostgreSQL 场景与性能测试之 18 - (OLAP) 用户画像圈人场景 - 数组包含查询与聚合》
4.2、数组的相似性, 例如相交的标签个数占比, 以及基于rank的排序
- 《HTAP数据库 PostgreSQL 场景与性能测试之 17 - (OLTP) 数组相似查询》
- 《沉浸式学习PostgreSQL|PolarDB 13: 博客、网站按标签内容检索, 并按匹配度(rank)排序》
插件
- smlar
- rum
索引
- gin
- rum
5、标量过滤(范围、等值、不等)
索引
- btree
- hash
- bloom
- brin
6、图
插件
语法
- openCypher
- SQL 递归
7、组合查询
7.1、某些插件支持融合查询的过滤及排序. 例如rum支持基于多值列的过滤, 同时支持addition info字段的排序(例如ts rank值的排序). 这种情况性能就比较好.
7.2、对于无法使用1个索引完成多个条件过滤的情况.
PG数据库会按需选择bitmap and OR bitmap or scan. bitmap scan会带来recheck, 结果集较大的情况下性能一般.
或者业务上进行设计, 如分区, 又如使用btree_gin, btree_gist融合索引.
- 《HTAP数据库 PostgreSQL 场景与性能测试之 47 - (OLTP多模优化) 空间应用 - 高并发空间位置更新、多属性KNN搜索并测(含空间索引)末端配送、新零售类项目》
- 《PostgreSQL UDF实现tsvector(全文检索), array(数组)多值字段与scalar(单值字段)类型的整合索引(类分区索引) - 单值与多值类型复合查询性能提速100倍+ 案例 (含,单值+多值列合成)》
8、其他.
paradedb产品, 致力于“AI+字面”的融合搜索.
1、镜像如下:
x86_64机器使用以下PostgreSQL docker image:
ARM64机器使用以下PostgreSQL docker image:
2、x86_64 机器使用方法:
# 拉取镜像, 第一次拉取一次即可. 或者需要的时候执行, 将更新到最新镜像版本.
docker pull registry.cn-hangzhou.aliyuncs.com/digoal/opensource_database:pg14_with_exts
# 启动容器
docker run --platform linux/amd64 -d -it -P --cap-add=SYS_PTRACE --cap-add SYS_ADMIN --privileged=true --name pg --shm-size=1g registry.cn-hangzhou.aliyuncs.com/digoal/opensource_database:pg14_with_exts
##### 如果你想学习备份恢复、修改参数等需要重启数据库实例的case, 换个启动参数, 使用参数--entrypoint将容器根进程换成bash更好. 如下:
docker run --platform linux/amd64 -d -it -P --cap-add=SYS_PTRACE --cap-add SYS_ADMIN --privileged=true --name pg --shm-size=1g --entrypoint /bin/bash registry.cn-hangzhou.aliyuncs.com/digoal/opensource_database:pg14_with_exts
##### 如果采用以上启动方式, 进入容器后, 需要手工启动数据库实例: su - postgres; pg_ctl start;
# 进入容器
docker exec -ti pg bash
# 连接数据库
psql
3、ARM64 机器使用方法:
# 拉取镜像, 第一次拉取一次即可. 或者需要的时候执行, 将更新到最新镜像版本.
docker pull registry.cn-hangzhou.aliyuncs.com/digoal/opensource_database:pg14_with_exts_arm64
# 启动容器
docker run -d -it -P --cap-add=SYS_PTRACE --cap-add SYS_ADMIN --privileged=true --name pg --shm-size=1g registry.cn-hangzhou.aliyuncs.com/digoal/opensource_database:pg14_with_exts_arm64
##### 如果你想学习备份恢复、修改参数等需要重启数据库实例的case, 换个启动参数, 使用参数--entrypoint将容器根进程换成bash更好. 如下:
docker run -d -it -P --cap-add=SYS_PTRACE --cap-add SYS_ADMIN --privileged=true --name pg --shm-size=1g --entrypoint /bin/bash registry.cn-hangzhou.aliyuncs.com/digoal/opensource_database:pg14_with_exts_arm64
##### 如果采用以上启动方式, 进入容器后, 需要手工启动数据库实例: su - postgres; pg_ctl start;
# 进入容器
docker exec -ti pg bash
# 连接数据库
psql