Skip to content

Latest commit

 

History

History
150 lines (50 loc) · 4.49 KB

20200429_01.md

File metadata and controls

150 lines (50 loc) · 4.49 KB

PostgreSQL 索引算子下推扩展 - 索引内offset - 索引内过滤 - include index - 随机偏移

作者

digoal

日期

2020-04-29

标签

PostgreSQL , 下推 , offset , 过滤 , 叶子 , include index , 随机偏移 , 内核


背景

抛出问题:

特征表, 表示用户的特征, 还有一个权重字段表示优先曝光(付费或者爆点可以让你的权重变大, 优先曝光). 根据相似特征推荐给我好友.

关系表, 用户关联了什么人.

特征表有一个向量索引, 根据特征搜索相似对象若干条. 然后按权重排序, 同时已经被我关联的对象, 不要再推荐给我.

问题在哪?

1、如果使用了向量相似搜索, 那么权重排序无法使用索引

2、如果你已经关联了很多人, 那么按相似搜索出来的对象可能很多都已经被你关联过, 会导致大量无效的索引扫描.

《PostgreSQL 向量相似推荐设计 - pase》

怎么解?

方法1:

将权重也放到特征向量里面, 作为一个维度, 每次查询的时候, 在权重这个维度上填入一个较为随机的值, 从而影响相似度, 每次推荐的记录有一定的随机性. 减少大量无效索引扫描.

打车热点一样的思路,加一个纠偏维度,随机直。干扰要小,例如10%取值范围, 影响小。 例如其他维度取值范围是0到100, 纠偏维度的范围可以是0到10, 减少最终向量距离的影响.

《PostgreSQL 滴滴派单 高峰区域集中打车冲突优化1 - 宇宙大爆炸理论与PostgreSQL实践》

方法2:

ivfflat索引, 支持指定从第N个桶开始返回. 类似offset.

方法3:

ivfflat, hnsw索引, 支持指定从第N条记录开始返回. 类似offset

方法4:

下推, 类似rum索引结构

《PostgreSQL rum 索引结构 - 比gin posting list|tree 的ctid(行号)多了addition info》

在索引的叶子节点中放入额外属性, 例如uid, 权重. 直接在索引中filter, 不需要回表后再filter.

实现思路:

ivfflat, 索引叶子, 可存储额外值(uid, weight), 查询是不仅能支持向量相似, 同时支持hll算子过滤和weight过滤.

这个思路与rum结构相似, 和include索引功能也比较相似.

《PostgreSQL index include - 类聚簇表与应用(append only, IoT时空轨迹, 离散多行扫描与返回)》

《PostgreSQL 12 preview - GiST 索引支持INCLUDE columns - 覆盖索引 - 类聚簇索引》

create index idx on tbl using rum (xx rum_addon_ops) with (addon=y,z) ;

create index idx on tbl using ivfflat (vec) include column(y,z);

select x from tbl where uid not in ... order by vec <?> array[...] limit 100;
-- 这里向量也用索引, uid过滤也在索引内完成.

select x from tbl where uid not in ... order by vec <?> array[...], weight desc limit 100;
-- 这里排序在索引内完成, 优先向量limit 100, 然后weight倒排.

PG 的access method接口非常灵活, 使得可以创造友好的存储结构, 以及对应的搜索和过滤算法。 就好比中国古语: 阴成形,阳化气。存储属阴,算法属阳。天地合而万物生,阴阳合而变化出。

您的愿望将传达给PG kernel hacker、数据库厂商等, 帮助提高数据库产品质量和功能, 说不定下一个PG版本就有您提出的功能点. 针对非常好的提议,奖励限量版PG文化衫、纪念品、贴纸、PG热门书籍等,奖品丰富,快来许愿。开不开森.

digoal's wechat