当前位置: 首页 > news >正文

PG 全文搜索实战(9):选型与避坑 · PG FTS vs Elasticsearch

本系列最后一篇。什么时候用 PG 全文搜索够了,什么时候该上 ES,以及一堆真实踩过的坑。

一、PG 全文搜索 vs Elasticsearch

维度PostgreSQL FTSElasticsearch
运维成本(已有 PG,不加组件)高(额外集群、同步、监控)
数据一致性(事务内,实时)最终一致(需同步,有延迟)
中文分词需装扩展,词库一般生态成熟(IK 等)
相关性/打分基础够用强大,可深度调优
聚合分析(facet、聚合)
海量 + 高并发搜索单机瓶颈明显天生分布式
高亮/纠错/联想基础丰富

二、决策建议(实战经验)

优先用 PG FTS,当:

  • 数据本来就在 PG,量级在千万级以内(或分区后单区可控)。
  • 搜索通常带过滤条件(时间、租户、分类),不是全库任意搜。
  • 要求搜索结果和业务数据强一致、实时
  • 团队不想多养一套 ES。

该上 ES,当:

  • 数据量上亿且需要全局任意关键词高并发检索。
  • 需要复杂的相关性调优、聚合分析、搜索联想/纠错。
  • 中文分词要求高,且 PG 装不了合适扩展(如云 RDS 受限)。
  • 已经有分表几十上百张,跨表全局搜索用 PG 很吃力(见第 8 章)。

经验法则:别一上来就 ES。先评估 PG FTS + 分区能不能扛,扛不住或明显不合适再上 ES。很多“搜索需求”其实 PG 就够了,省下一套中间件的运维。

三、真实踩坑清单

1. NULL 导致 tsvector 整个为空

-- ❌ title 为 NULL 时,整个 tsvector = NULL,搜不到to_tsvector('english',title||' '||body)-- ✅ 用 coalesce 兜底to_tsvector('english',coalesce(title,'')||' '||coalesce(body,''))

2. 建索引配置和查询配置不一致

建索引用english,查询用simple(或中文用了不同配置),结果匹配不上两边必须完全一致。

3. 表达式索引没命中

to_tsvector('english', title || ' ' || body)建的索引,查询表达式必须逐字一致(连拼接顺序、空格都要一样)才走索引。推荐用生成列避免这个坑。

4. 用户输入直接喂 to_tsquery 报错

to_tsquery要求合法语法,用户输入a & & b之类会抛异常。接收前端输入一律用websearch_to_tsquery

5. ts_headline 拖垮查询

对全表做高亮 = 灾难。只对分页后的当前页做(见第 5 章)。

6. 小数据量 EXPLAIN 看不到用索引

数据少时 PG 认为全表扫更快,不用 GIN,这是正常的优化器行为,不是索引坏了。数据量上来自然会用。

7. 大表直接 ADD COLUMN GENERATED 锁表

亿级表一把梭会锁很久。先加空列、分批回填、CONCURRENTLY 建索引(见第 7 章)。

8. 改了词库/配置,老数据不生效

分词配置或自定义词典变更后,历史行的 tsvector 不会自动重算,需要 rebuild(重跑 UPDATE 或重建生成列)。

9. 云 RDS 装不了 zhparser

采购前确认云数据库是否支持中文分词扩展,否则中文搜索会很尴尬。

四、一句话总结全系列

PG 全文搜索 = tsvector(预计算落列)+ GIN 索引 + tsquery 匹配 + ts_rank 排名。
中小规模、数据在 PG、搜索带过滤条件的场景,它完全够用,且省一套 ES 的运维。数据到海量、要全局高并发检索和复杂分析时,再上 ES。


http://www.jsqmd.com/news/1227932/

相关文章:

  • 2026年国内玻璃钢冷却塔厂家排行 适配多场景选购参考 - 热点速览
  • Beyond Compare 5终极解决方案:深度解析BCompare_Keygen密钥生成器的技术实现与实战应用
  • RPG Maker游戏资源提取器:免费解密工具完整使用教程
  • 终极解决方案:Visual C++ Redistributable AIO一键解决Windows运行库依赖
  • OpenCore Legacy Patcher完整教程:五步让老Mac焕发新生
  • OpenOnload高级调优:如何根据应用特性定制网络栈参数
  • MacBook USB-C不充电故障诊断:从PD握手到主板供电链路
  • HiveWE架构深度解析:现代化魔兽争霸III地图编辑器技术实现
  • 2026年影音酒店抖音直播代运营:影峰影音服务模式客观科普 - 速递信息
  • Loop:5分钟掌握macOS优雅窗口管理的终极指南
  • 2026年硕景园林古建牌楼服务梳理及国内优质施工企业盘点 - 每天一杯纯牛奶
  • C++实现192BCH编解码算法:从有限域理论到高性能工程实践
  • GoFakeS3未来路线图:即将推出的7大新功能预览
  • 【DQN实现避障控制】使用Pytorch框架搭建神经网络,基于DQN算法、优先级采样的DQN算法、DQN + 人工势场实现避障控制研究附Matlab、Python代码
  • 7-Zip-Zstandard:解决传统压缩工具性能瓶颈的现代压缩解决方案
  • 掌握circuitpython-tricks的Neopixel控制:打造惊艳的LED灯光效果
  • 口音语音识别实战:从数据采集到鲁棒ASR落地
  • OpenDCAI/OpenWorldLib中的世界模型定义:理解感知、交互与长期记忆
  • A股市场动能解析:政策、资金与结构性机会
  • FlappyBird Java实现:如何用纯Java编写2D游戏引擎
  • Windows系统必备:VisualCppRedist全合一运行库解决方案深度解析
  • 实测日记|2026论文双检翻车实录!普通AI vs okbiye差距到底有多大?看完少走100条弯路
  • 多语言 Hreflang 标签 建站 配置 | 让外贸站流量涨3倍的底层代码
  • 2026 年 7 月权威核验渠道,百达翡丽官方维修服务中心国内官方售后地址 热线防坑对照清单 - 百达翡丽官方服务中心
  • Unity跨平台文件对话框实现:抽象接口与多平台适配方案
  • OpenAI Codex命令行编程助手:安装配置与核心功能详解
  • 2026年霞浦海参工厂分类与生产标准百科解读
  • 深度解析:当 Swift 遇上 Apple Silicon,Mattermost 如何重塑 Mac 容器开发体验
  • C++文件操作全解析:从流机制到跨平台实战与性能优化
  • 数据预处理不是写代码,而是给数据做外科手术