注意: 这种情况千万不要使用分区表
这种全文检索: 不要使用分区表
https://github.com/timescale/pg_textsearch
pg_testsearch 用来计算 bm25 得分的信息是不是存储在索引中, 由于 PG 没有全局索引, 所以使用分区表时, 跨分区按 bm25 得分排序是无意义的.
是的,您的理解是正确的。pg_textsearch 确实将计算 BM25 得分所需的信息存储在索引中,但对于分区表,每个分区维护自己的统计信息,这使得跨分区按 BM25 得分排序可能没有意义。
核心原因
pg_textsearch 在分区表上使用分区本地统计信息 。每个分区独立维护:
文档总数 ( total_docs)平均文档长度 ( avg_doc_len)用于 IDF 计算的每词文档频率
实际影响
这意味着:
单分区查询:使用该分区的统计信息计算准确的 BM25 得分 跨分区查询:每个分区的得分使用不同的统计信息独立计算,可能无法直接比较
测试文件中的示例清楚地展示了这一点 :
-- 小分区(3个文档)中 'database' 的得分
SELECTcontent, ROUND((content <@> 'database')::numeric, 4) as score
FROM partition_small;
-- 结果:-0.4901
-- 大分区(10个文档)中 'database' 的得分
SELECTcontent, ROUND((content <@> 'database')::numeric, 4) as score
FROM partition_large;
-- 结果:-1.4816
相同的查询词在不同分区中产生不同的得分,因为 IDF 值依赖于分区本地的文档总数和词频统计。
建议
对于时间分区数据,当得分可比性重要时,建议将时间分区窗口拉到查询需求的最大范围 使用查询自然针对单个分区的分区方案 在设计搜索工作负载的分区策略时考虑此行为
Notes
BM25 得分计算本身在 bm25_text_bm25query_score 函数中实现 ,该函数会从索引中获取必要的统计信息来计算得分。对于分区表,这些统计信息是分区级别的,不是全局的。
最后附一则PG与IvorySQL年度峰会的消息,欢迎报名来济南面基,我是新特性分论坛出品人,欢迎报名参与分享,主委会可解决分享嘉宾住宿和路费。报名地址: https://jsj.top/f/uebqBc