pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。
在内部,一个 GIN 索引包含一个基于键构建的 B-tree 索引,其中每个键都是被索引值的一个元素(例如数组成员), 而叶子页中的每个元组要么是指向堆指针 B-tree 的指针 (PT,posting tree),要么在列表足够小时是堆指针的列表 (PL,posting list)。
由于倒排索引的内在性质,更新 GIN 索引往往 比较慢:插入或更新一个堆行,可能会导致向索引中执行多次插入 (从被索引值中提取出的每个键都要插入一次)。从 PostgreSQL 8.4 开始, GIN 可以通过把新元组插入一个临时的、未排序的待处理 列表,来推迟其中的大部分工作。当表被清理时,或者待处理列表 变得过大(大于 work_mem)时,这些项就会被 移入主要的 GIN 数据结构中,所用的是与初始 索引创建时相同的批量插入技术。即便把额外的清理开销计算在内, 这也会大幅提高 GIN 索引的更新速度。此外, 这部分开销工作还可以由后台进程完成,而不是在前台查询处理过程 中完成。
这种方法的主要缺点是,搜索除了要查找常规索引之外,还必须扫描待处理列表, 因此大型待处理列表会显著拖慢搜索。另一个缺点是,虽然大多数更新都很快, 但一旦某次更新使待处理列表变得“过大”,就会立刻触发一次清理周期, 因此该次更新会比其他更新慢得多。恰当地使用自动清理可以将这两个问题都尽量减轻。
如果稳定的响应时间比更新速度更重要,可以通过关闭 GIN 索引的 FASTUPDATE 存储参数来禁用待处理列表机制。详见 CREATE INDEX。
GIN 可以支持“部分匹配”查询。在这种查询中,查询 无法确定一个或多个键的精确匹配,但可能的匹配会落在一个相对 狭窄的键值范围内(该范围位于由 compare 支持方法 确定的键排序顺序中)。extractQuery 方法不是返回 一个要精确匹配的键值,而是返回待搜索范围的下界键值,并将 pmatch 标志设为 true。随后使用 comparePartial 方法扫描该键范围。对于匹配的索引键, comparePartial 必须返回零;对于虽然不匹配但仍处在 待搜索范围内的索引键,返回小于零;如果索引键已经超出了可能 匹配的范围,则返回大于零。
译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。