世纪难题: 多模融合查询
文章开始前推荐2个学习环境:
1、欢迎使用镜像快速体验PostgreSQL/DuckDB强大功能:《最好的PostgreSQL学习镜像》
2、欢迎使用云起实验室: 《免费体验PolarDB开源数据库》
3、PolarDB开源数据库内核、应用等学习图谱: https://www.aliyun.com/database/openpolardb/activity
标签
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做比较强大的计算+搜索引擎. )
《PostgreSQL pg_bm25(open source by paradedb):Postgres 内部的弹性质量全文搜索 性能优于tsvector tsrank 20x》
《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 2 smlar插件详解》
《PostgreSQL结合余弦、线性相关算法 在文本、图片、数组相似 等领域的应用 - 1 文本(关键词)分析理论基础 - TF(Term Frequency 词频)/IDF(Inverse Document Frequency 逆向文本频率)
》
索引
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
《PostgreSQL RUM 索引原理》
《PostgreSQL rum 索引结构 - 比gin posting list|tree 的ctid(行号)多了addition info》
《PostgreSQL 相似搜索插件介绍大汇总 (cube,rum,pg_trgm,smlar,imgsmlr,pg_similarity) (rum,gin,gist)》
《从难缠的模糊查询聊开 - PostgreSQL独门绝招之一 GIN , GiST , SP-GiST , RUM 索引原理与技术背景》
5、标量过滤(范围、等值、不等)
索引
btree
hash
bloom
《重新发现PostgreSQL之美 - 14 bloom 布隆过滤器索引》
《PostgreSQL 9.6 黑科技 bloom 算法索引,一个索引支撑任意列组合查询》
《PostgreSQL bloom 索引原理》
brin
《重新发现PostgreSQL之美 - 13 brin 时序索引》
《PostGIS空间索引(GiST、BRIN、R-Tree)选择、优化 - 2》
《HTAP数据库 PostgreSQL 场景与性能测试之 24 - (OLTP) 物联网 - 时序数据并发写入(含时序索引BRIN)》
《自动选择正确索引访问接口(btree,hash,gin,gist,sp-gist,brin,bitmap...)的方法》
6、图
插件
age https://github.com/apache/age
语法
openCypher
SQL 递归
《PostgreSQL 图式搜索(graph search)实践 - 百亿级图谱,毫秒响应》
7、组合查询
7.1、某些插件支持融合查询的过滤及排序. 例如rum支持基于多值列的过滤, 同时支持addition info字段的排序(例如ts rank值的排序). 这种情况性能就比较好.
7.2、对于无法使用1个索引完成多个条件过滤的情况.
PG数据库会按需选择bitmap and OR bitmap or scan. bitmap scan会带来recheck, 结果集较大的情况下性能一般.
《PostgreSQL bitmapAnd, bitmapOr, bitmap index scan, bitmap heap scan》
或者业务上进行设计, 如分区, 又如使用btree_gin, btree_gist融合索引.
《HTAP数据库 PostgreSQL 场景与性能测试之 47 - (OLTP多模优化) 空间应用 - 高并发空间位置更新、多属性KNN搜索并测(含空间索引)末端配送、新零售类项目》
[《PostgreSQL UDF实现tsvector(全文检索), array(数组)多值字段与scalar(单值字段)类型的整合索引(类分区索引) - 单值与多值类型复合查询性能提速100倍+ 案例 (含,单值+多值列合成)》](../201802/- 20180207_02.md)
8、其他.
paradedb产品, 致力于“AI+字面”的融合搜索.
https://github.com/paradedb/paradedb
本文涉及的插件在宇宙最强镜像中都有, 可以自己去体验
1、镜像如下:
x86_64机器使用以下PostgreSQL docker image:
《amd64 image》
ARM64机器使用以下PostgreSQL docker image:
《arm64 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
欢迎关注我的github (https://github.com/digoal/blog) , 学习数据库不迷路.
近期正在写公开课材料, 未来将通过视频号推出, 欢迎关注视频号:
文章中的参考文档请点击阅读原文获得.