Kir*_*sev 15 postgresql index null index-tuning
我有一个包含大量插入内容的表,将其中一个字段 ( uploaded_at) 设置为NULL. 然后周期性任务选择所有元组WHERE uploaded_at IS NULL,处理它们并更新,设置uploaded_at为当前日期。
我应该如何索引表?
我知道我应该使用部分索引,例如:
CREATE INDEX foo ON table (uploaded_at) WHERE uploaded_at IS NULL
Run Code Online (Sandbox Code Playgroud)
或者像那样。我有点困惑,但如果在始终为NULL. 或者如果使用 b 树索引是正确的。Hash 看起来是一个更好的主意,但它已经过时并且不能通过流式热备复制进行复制。任何建议将不胜感激。
我对以下索引进行了一些试验:
"foo_part" btree (uploaded_at) WHERE uploaded_at IS NULL
"foo_part_id" btree (id) WHERE uploaded_at IS NULL
Run Code Online (Sandbox Code Playgroud)
并且查询平面似乎总是选择foo_part索引。索引的explain analyse结果也稍好一些foo_part:
Index Scan using foo_part on t1 (cost=0.28..297.25 rows=4433 width=16) (actual time=0.025..3.649 rows=4351 loops=1)
Index Cond: (uploaded_at IS NULL)
Total runtime: 4.060 ms
Run Code Online (Sandbox Code Playgroud)
对比
Bitmap Heap Scan on t1 (cost=79.15..6722.83 rows=4433 width=16) (actual time=1.032..4.717 rows=4351 loops=1)
Recheck Cond: (uploaded_at IS NULL)
-> Bitmap Index Scan on foo_part_id (cost=0.00..78.04 rows=4433 width=0) (actual time=0.649..0.649 rows=4351 loops=1)
Total runtime: 5.131 ms
Run Code Online (Sandbox Code Playgroud)
Erw*_*ter 11
在这种特殊情况下,实际索引的列与手头的查询无关。您可以选择任何列。我会选择除 之外的其他东西uploaded_at,这是无用的。某些列可能对其他查询有用,理想情况下不大于 8 个字节。
CREATE INDEX foo ON table bar (some_col) WHERE uploaded_at IS NULL;
Run Code Online (Sandbox Code Playgroud)
如果你没有任何其他列的用例,最好还是坚持使用无用的uploaded_at,这样就不要为索引引入额外的维护成本和对 HOT 更新的限制。更多的:
或者,如果您没有使用任何其他索引列,则使用常量作为索引表达式。喜欢:
CREATE INDEX baz ON table bar ((TRUE)) WHERE uploaded_at IS NULL;Run Code Online (Sandbox Code Playgroud)
需要括号。这也使索引保持在最小大小。但是,尽管索引列永远不会大于 8 个字节(对于 而言就是这种情况timestamp),它仍然处于最小大小。有关的:
| 归档时间: |
|
| 查看次数: |
11680 次 |
| 最近记录: |