在 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 的子集之上。但是,我有几个与此相关的问题:
- Postgres 是否在
billed is not true
内部存储另一个索引以快速找到与部分索引关联的行?
- 如果 (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 知道它可以使用索引并且不必检查索引条件,因为它会自动满足。
所以:
不,通过索引找到的任何行都会自动满足索引条件,所以使用索引足以确保满足。
不,不会用index on a boolean column,因为它不会比这个partial index便宜,而且partial index可以用来检查[=11=上的条件] 还有。
实际上是相反的:部分索引可以很好地用于在 WHERE
条件中只有 boolean
列的查询,如果满足条件。
我正在尝试推理 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 的子集之上。但是,我有几个与此相关的问题:
- Postgres 是否在
billed is not true
内部存储另一个索引以快速找到与部分索引关联的行? - 如果 (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 知道它可以使用索引并且不必检查索引条件,因为它会自动满足。
所以:
不,通过索引找到的任何行都会自动满足索引条件,所以使用索引足以确保满足。
不,不会用index on a boolean column,因为它不会比这个partial index便宜,而且partial index可以用来检查[=11=上的条件] 还有。
实际上是相反的:部分索引可以很好地用于在
WHERE
条件中只有boolean
列的查询,如果满足条件。