我正在对我们项目中最大的表之一进行性能调整。在阅读有关索引的内容时,我遇到了部分索引。这听起来是一个非常好的主意,只包含经常访问的行。
但我无法弄清楚部分索引是如何更新的。例如,我有一个包含以下列的表格:
task_uuid, job_id, enqueued_at, updated_at, task_status
task_status
可以是:ENQUEUED、RUNNING、ASSIGNED、FAILED。
我们非常频繁地搜索处于ENQUEUED
状态的记录。如果我们在 (task_uuid, task_status)
上添加部分索引,它将构建一个唯一的键并提高性能。但是,当该行更新为 RUNNING 状态时会发生什么? (task_uuid, task_status)
仍然是唯一的,但是它会从部分索引中删除吗?该记录不再满足条件。
最佳答案
If we add a partial index on (task_uuid, task_status) it will build a unique key and improve the performance.
如果您在索引定义中指定,它只会将其构建为唯一的。否则它就不是唯一索引,即使这些列也恰好是唯一的。
当记录被更新而不再与索引的 WHERE 谓词匹配时,索引不会发生任何变化。它仍然有一个指向该行的指针,它只是指向不再有效的东西。如果您确实将索引指定为 UNIQUE,那么在插入冲突的索引元组时,它将跟随旧元组的指针指向表,意识到它是无效的,并允许继续插入。
下次清理表时,那些过时的指针将被清除。具有部分索引的队列表通常应该经常被清理(比默认更频繁),因为索引很容易膨胀。 Autovac 设置取决于废弃的表行的比例,而不是废弃的索引行的比例。对于部分索引,这些分数并不相同。 (另一方面,您似乎没有“COMPLETED”状态。如果立即删除已完成的任务,也许队列表将保持足够小,这并不重要。)
此外,当索引扫描跟踪从索引到表的指针并发现该行不再对任何人可见时,它会将索引条目标记为死亡。这样以后的索引扫描就不必无意义地跳转到表。但这种“微真空”仅发生在常规索引扫描中,而不是位图扫描中,并且仅发生在主服务器上完成的查询中,而不发生在热备用上完成的任何查询中。
关于database - PostgreSQL 中的部分索引何时更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63340013/