2-5.全文索引与并行查询

全文索引与并行查询

全文索引

介绍

PostgreSQL 内置了全文检索功能,但默认仅支持英文检索。

可通过配置插件(如 zhparser)实现对中文的全文检索。

全文检索初步使用

PostgreSQL 将长文本分解为许多 token 的集合,称为 tsvector,代表文档内容。检索实际上是在 token 集合中进行的。

示例
sql 复制代码
-- 将文本转为 tsvector
SELECT 'we love postgresql database'::tsvector;
-- 使用函数分词
SELECT to_tsvector('we love postgresql database');

检索条件类型为 tsquery,是由简单逻辑运算符组成的字符串。

sql 复制代码
SELECT 'postgresql & love'::tsquery;
SELECT to_tsquery('postgresql & love');

全文检索使用 tsvectortsquery 进行匹配,运算符为 @@

sql 复制代码
SELECT 'we love postgresql database'::tsvector @@ 'postgresql & love'::tsquery; -- true
SELECT 'we love postgresql database'::tsvector @@ 'mysql | love'::tsquery;      -- true
SELECT 'we love postgresql database'::tsvector @@ 'mysql & love'::tsquery;      -- false

使用全文检索实际案例

建表并插入数据
sql 复制代码
CREATE TABLE myblog (
    id INT PRIMARY KEY,
    content TEXT,
    content_tsv TSVECTOR
);

-- 插入 100 万条记录
INSERT INTO myblog(id, content)
SELECT seq, 'PostgresQL' || seq || ' MySQL' || (seq + 10)
FROM generate_series(1, 1000000) AS seq;

-- 分词处理
UPDATE myblog SET content_tsv = to_tsvector(content);
查询示例
sql 复制代码
-- 查询包含 "postgresql1323" 的记录
SELECT * FROM myblog WHERE content_tsv @@ 'postgresql1323'::tsquery;
EXPLAIN SELECT * FROM myblog WHERE content_tsv @@ 'postgresql1323'::tsquery;

此时会进行全表扫描,性能较差。

创建 GIN 索引加速
sql 复制代码
CREATE INDEX idx_myblog_content_tsv ON myblog USING GIN(content_tsv);

-- 再次查询
SELECT * FROM myblog WHERE content_tsv @@ 'postgresql1323'::tsquery;
EXPLAIN SELECT * FROM myblog WHERE content_tsv @@ 'postgresql1323'::tsquery;

使用 zhparser 做中文全文检索

安装依赖
  1. 安装 PostgreSQL 开发包(以 PostgreSQL 15 为例):

    bash 复制代码
    yum install postgresql15-devel
  2. 安装 scws(中文分词器):

    bash 复制代码
    wget -q http://www.xunsearch.com/scws/down/scws-1.2.3.tar.bz2
    tar xvf scws-1.2.3.tar.bz2
    cd scws-1.2.3
    ./configure
    make
    make install
  3. 安装 zhparser 插件(需从 GitHub 下载编译)。

配置与使用
sql 复制代码
-- 创建扩展
CREATE EXTENSION zhparser;

-- 创建中文全文检索配置
CREATE TEXT SEARCH CONFIGURATION testzhcfg (PARSER = zhparser);
ALTER TEXT SEARCH CONFIGURATION testzhcfg
ADD MAPPING FOR n,v,a,i,e,l WITH simple;
  • n, v, a, i, e, l 表示不同的 Token 策略,启用了这些 Token Mapping。
  • 使用 \dfp+ zhparser 查看详细含义。
示例表与数据
sql 复制代码
CREATE TABLE myblog (
    id INT PRIMARY KEY,
    content TEXT,
    content_tsv TSVECTOR
);

INSERT INTO myblog(id, content) VALUES
(1, '中国南京市长江大桥'),
(2, '是一种特性非常齐全的自由软件的对象-关系型数据库管理系统'),
(3, '是以加州大学计算机系开发的POSTGRES'),
(4, '4.2版本为基础的对象关系型数据库管理系统'),
(5, 'PostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统(RDBMS)'),
(6, 'PostgreSQL是一个非常健壮的软件包,有很多在大型商业RDBMS中所具有的特性'),
(7, '包括事务、子选择、触发器、视图、外键引用完整性和复杂锁定功能'),
(8, '全球开发组今天宣布,世界上功能最为强大的开源数据库发布');

-- 使用 testzhcfg 配置分词
UPDATE myblog SET content_tsv = to_tsvector('testzhcfg', content);

-- 创建 GIN 索引
CREATE INDEX idx_myblog_content_tsv ON myblog USING GIN(content_tsv);
中文全文检索查询
sql 复制代码
-- 检索包含"南京市"的文档
SELECT * FROM myblog WHERE content_tsv @@ to_tsquery('testzhcfg', '南京市');

-- 中文检索中也可查询英文单词
SELECT id, content FROM myblog WHERE content_tsv @@ to_tsquery('testzhcfg', 'postgresql');

并行查询功能

并行查询利用多 CPU 和多核的能力,可显著缩短大数据量查询的处理时间。

并行查询相关配置参数

参数名 说明
dynamic_shared_memory_type 必须设置为非 none 值,用于进程间数据传递
max_worker_processes 整个数据库实例允许的最大后台工作进程数(默认 8)
max_parallel_workers 整个实例允许用于并行的后台工作进程数
max_parallel_workers_per_gather 单个并行操作允许的并行度(需小于 max_parallel_workers
min_parallel_table_scan_size 表大小小于此值时不走并行(默认 8MB)
min_parallel_index_scan_size 索引扫描大小小于此值时不走并行(默认 512KB)
成本估算参数
  • parallel_setup_cost:并行启动成本
  • parallel_tuple_cost:并行处理每行数据的成本

是否使用并行取决于 CBO(成本优化器)的计算结果。若非并行的成本低于并行成本,则不使用并行。

强制并行模式
sql 复制代码
SET force_parallel_mode = on;  -- 慎用于生产环境,一般用于测试

支持的并行操作

操作类型 说明
并行顺序扫描 全表扫描(sequential scan)
并行索引扫描 索引扫描(index scan)
并行 index-only 扫描 index only 扫描
并行 bitmap heap 扫描 bitmap heap 扫描
并行聚合 COUNT()SUM() 等聚合操作
Nested loop 并行 Nested loop 多表关联
Merge join 并行 Merge join 多表关联
Hash Join 并行 Hash Join 多表关联
并行 create index BTree 索引的并行创建
CREATE TABLE ... AS 支持并行执行

总结

功能 关键点
全文索引 内置英文检索,通过插件支持中文;使用 tsvector/tsquery 和 GIN 索引
zhparser 需安装 scws 分词器,配置 Token Mapping,支持中英文混合检索
并行查询 利用多核 CPU,需配置相关参数;CBO 决定是否并行;支持多种扫描与连接操作

相关推荐
360智汇云3 小时前
PostgreSQL 全文检索深度指南:内置 FTS、zhparser 与 pg_search 全解
postgresql·django·全文检索
有想法的py工程师4 小时前
PostgreSQL 性能优化实战:一条 Order by 的 SQL 从 5 秒优化到 100ms
大数据·数据库·postgresql·性能优化
翻斗包菜1 天前
PostgreSQL 日常维护完全指南:从基础操作到高级运维
运维·数据库·postgresql
刘晨鑫12 天前
PostgreSQL日常维护
数据库·postgresql
百结2142 天前
postgresql日常运用
数据库·postgresql·oracle
_下雨天.2 天前
PostgreSQL日常维护
数据库·postgresql
|华|2 天前
PostgreSQL日常维护
数据库·postgresql
l1t2 天前
DeepSeek总结的PAX:PostgreSQL存储引擎
数据库·postgresql
我不听你讲话2 天前
PostgreSQL 日常维护核心内容总结
数据库·postgresql