在 Postgres 中索引部分索引的条件

Indexing the condition of a partial index in Postgres

我正在尝试推理 Postgres partial indexes 是如何存储在 Postgres 中的。假设我创建一个这样的索引

CREATE INDEX orders_unbilled_index ON orders (order_nr)
WHERE billed is not true

为了快速运行查询

SELECT *
FROM orders
WHERE billed is not true AND order_nr > 1000000

Postgres 显然在 order_nr 上存储了一个索引,该索引建立在条件表达式 billed is not true 定义的 orders table 的子集之上。但是,我有几个与此相关的问题:

  1. Postgres 是否在 billed is not true 内部存储另一个索引以快速找到与部分索引关联的行?
  2. 如果 (1) 不是这种情况,如果我在 billed is not true 上创建一个单独的索引,它会使得上面的查询更快 运行 吗? (假设一个大 table 和几行 billed is true

编辑: 由于 how boolean indexes are rarely used,我基于文档的示例查询不是最好的,但请在任何条件表达式的上下文中考虑我的问题。

据我了解,Postgres 将简单地建立一个索引,该索引只能用于查找 billed 为不正确的记录。也就是说,结果 B-tree 将由 order_nr 索引,但当 billed 为假时,只会 link 返回到原始 table。

如果您继续阅读 documentation,在您引用的内容之后,您会发现以下查询作为示例:

SELECT * FROM orders WHERE billed is not true AND amount > 5000.00;

在这种情况下,Postgres 可能 甚至选择使用您在上述查询中定义的索引。它可以使用您的索引通过扫描整个索引来满足此查询。如果尚未开票的订单数量相对较少,那么在 order_nr 上扫描索引可能仍然比进行完整的 table 扫描更可取。

因此,问题 #1 的答案是不,billed 没有单独的索引,而是 order_nr 上的索引只能用于具有 billed 设置为假。对于#2,是的,可以使用 billed is not true 上的第二个索引,假设很少有未开票的记录。但是,即使您当前的索引也可能按原样使用。

一个b-tree索引可以被认为是一个有序的索引条目列表,每个条目都有一个指向table.

中一行的指针

在部分索引中,列表更小:只有满足条件的行的索引条目。

如果你的 WHERE 子句中有索引条件,PostgreSQL 知道它可以使用索引并且不必检查索引条件,因为它会自动满足。

所以:

  1. 不,通过索引找到的任何行都会自动满足索引条件,所以使用索引足以确保满足。

  2. 不,不会用index on a boolean column,因为它不会比这个partial index便宜,而且partial index可以用来检查[=11=上的条件] 还有。

    实际上是相反的:部分索引可以很好地用于在 WHERE 条件中只有 boolean 列的查询,如果满足条件。