PostgreSQL GIN 提示和技巧
- 创建 vs. 插入
插入到一个GIN索引可能会很慢,因为为一个项可能需要插入很多歌键。因此,对于一个表的批量插入,我们建议删除 GIN 索引,然后在完成批量插入后重建它。
从PostgreSQL 8.4 开始,这个建议已经不再需要了,因为可以使用延迟索引(详见第 66.4.1 节)。但是对于非常大量的更新,还是最好先删除再重建索引。
- maintenance_work_mem
一个GIN索引的建立时间对
maintenance_work_mem
设置很敏感;它不考虑在索引创建期间在工作内存上的节省。- gin_pending_list_limit
在向一个已有的开启了
fastupdate
的GIN 中进行插入时,系统将在待处理项列表增长到超过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)比较好。