值大致相同的列的最佳索引

who*_*ked 9 postgresql index postgresql-9.6

我们有一个整数列,目前仅包含 0 或 1 个值。此列现在已被开发人员用于在某些情况下存储唯一的 32 位标识符,我们需要能够有效地提取包含这些标识符中的任何一个的行。

鉴于该值在 99% 的情况下是 0 或 1(我还没有数字),如何最好地索引以查询少数情况?我认为共同价值的数量将成为一个问题是否正确?

           Column           |  Type   |     Modifiers
----------------------------+---------+--------------------
 event_value                | integer | not null
Run Code Online (Sandbox Code Playgroud)

此列当前没有索引。而且我不认为需要定期只选择 0 或 1 值。

该表大小合理,目前有 3000 万行并且增长很快。

我很欣赏这不是该专栏的最佳用途,但在短期内不会改变。

Erw*_*ter 6

首先,就像你自己说的那样,最好不要使用列。应该是一个独立的booleaninteger为贵“的32位标识符”一栏。如果那是NULL99% 的时间,那没问题。NULL存储非常便宜。

无论哪种方式,您都应该使用部分索引。(这是手册中使用的正确术语。)从索引中排除 99% 的行会使其变得非常小,这对数百万行的性能很重要

但是,如果您有一个完整的索引event_value,并且您的常见查询正在检索单行,例如:

SELECT * FROM tbl WHERE event_value = 123;
Run Code Online (Sandbox Code Playgroud)

...然后额外的部分指数不会买太多。它仍然会被使用,因为它仍然有点快,但并不比完整索引快多少。额外索引的成本可能会超过收益。

虽然罕见的值是“32 位标识符”,但假设它们都 > 1 可能是不正确的。Postgres 使用有符号整数,并且 32 位实体也将涵盖负数。(我们甚至可以排除01作为这些标识符之一吗?)如果也可以有负值:

CREATE INDEX tbl_event_value_part_idx ON tbl (event_value)
WHERE event_value > 1 OR event_value < 0; -- or similar
Run Code Online (Sandbox Code Playgroud)

event_value不必是索引列,无论它在 WHERE 子句中的使用如何。这完全取决于预期的查询类型。无论哪种方式,安全的赌注是将相同的WHERE条件逐字添加到任何应该使用索引的查询中,即使这在逻辑上是多余的。Postgres 可以做出非常基本的逻辑结论来确定适用的索引,但它不是人工智能,也不会尝试(会很快变得太昂贵)。喜欢:

SELECT * FROM tbl WHERE event_value > 1 OR event_value < 0
Run Code Online (Sandbox Code Playgroud)

有关的: