database - PostgreSQL 中的部分索引何时更新?

标签 database postgresql indexing partial-index

我正在对我们项目中最大的表之一进行性能调整。在阅读有关索引的内容时,我遇到了部分索引。这听起来是一个非常好的主意,只包含经常访问的行。

但我无法弄清楚部分索引是如何更新的。例如,我有一个包含以下列的表格:

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/

相关文章:

mysql - 我什么时候应该将 JSON 存储在数据库中?

当 WHERE 不匹配时返回具有特定 NULL 值的记录的 SQL 查询

sql - 为什么我使用 LIKE 的查询执行序列扫描?

mysql - 我如何让erlang连接到mysql?

mysql - 使用前 2 个条目的值将移动平均列添加到表中

c++ - 聚集键/值数据库 : most recent record

postgresql - 使用 Netbeans 6.9.1 从 postgresql 9.0.1 数据库创建实体

python - 连接到列中带有字符ñ的postgresql表时如何在Python中设置sqlalchemy

sql - 联合主键中包含的索引列

mysql - 如何操纵 MySQL 全文搜索相关性以使一个字段比另一个字段更多 'valuable'?