1

我试图推断 Postgres 部分索引是如何存储在 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的表子集上的索引。但是,我有几个与此相关的问题:ordersbilled is not true

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

编辑:由于布尔索引很少使用,我基于文档的示例查询并不是最好的,但请在任何条件表达式的上下文中考虑我的问题。

4

2 回答 2

2

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

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

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

所以:

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

  2. 不,不会使用布尔列上的索引,因为它不会比这个部分索引便宜,并且部分索引也可以用来检查条件order_nr

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

于 2020-09-06T12:08:45.887 回答
0

据我了解,Postgres 只会建立一个索引,该索引只能用于查找billed不真实的记录。也就是说,生成的 B-tree 将由 索引,但只有在为 falseorder_nr时才会链接回原始表。billed

如果您继续阅读文档,在您引用的内容之后,您会立即找到以下查询作为示例:

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

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

所以,你的问题 #1 的答案是不,没有单独billed的索引 ,而是索引 on order_nronly 可用于billed设置为 false 的记录。对于#2,是的,billed is not true假设很少有记录未计费,则可以使用第二个索引。但是,即使您当前的索引也可能按原样使用。

于 2020-09-06T04:39:48.870 回答