64.5. GIN 提示和技巧

创建 vs. 插入

插入到一个GIN索引可能会很慢,因为为一个项可能需要插入很多歌键。因此,对于一个表的批量插入,我们建议删除 GIN 索引,然后在完成批量插入后重建它。

PostgreSQL 8.4 开始,这个建议已经不再需要了,因为可以使用延迟索引(详见第 64.4.1 节)。但是对于非常大量的更新,还是最好先删除再重建索引。

maintenance_work_mem

一个GIN索引的建立时间对maintenance_work_mem设置很敏感;它不考虑在索引创建期间在工作内存上的节省。

gin_pending_list_limit

在向一个已有的开启了fastupdateGIN 中进行插入时,系统将在待处理项列表增长到超过gin_pending_list_limit 时清理该列表。为了避免在观测到的响应时间上出现波动,让待处理列表清理操作 在后台进行(即通过 autovacuum)比较好。可以通过增加gin_pending_list_limit 或者让 autovacuum 更激进来避免前台的清理操作。不过,增大清理操作的 阈值意味着如果一次前台清理发生,它将需要更长的时间。

可以通过改变存储参数为每个 GIN 索引覆盖它所用的gin_pending_list_limit, 这样允许每个 GIN 索引拥有自己的清理阈值。例如,可以只为被大量更新的 GIN 索引增加 该阈值,而对其他的索引减小该阈值。

gin_fuzzy_search_limit

开发GIN索引的主要目的是在PostgreSQL中创建对高可扩展全文搜索的支持,并且一次全文搜索返回一个非常大的结果集也是很常见的情况。此外,当查询包含非常频繁的词时情况也是如此,因此大结果集不是非常有用。因为从磁盘读取很多元组并且对它们排序可能会花费很多时间,这对于产品来说是不可接受的(注意索引搜索本身是很快的)。

为了能够控制这类查询的执行,GIN对于返回的行数有一个可配置的软上限:gin_fuzzy_search_limit配置参数。默认它被设置为 0 (意为无限制)。如果设置了一个非零限制,那么被返回的集合是整个结果集的一个子集,并且是随机选择的。

意味着被返回结果的实际数量可以与指定的限制不同,这取决于查询和系统随机数生成器的质量。

根据经验,在数千级别的值(如 5000 — 20000)比较好。