PostgreSQL 官方文档提供了以下有关部分索引的示例:
示例 11.2。设置部分索引以排除不感兴趣的值
如果您有一个表同时包含已开票订单和未开票订单,其中未开票订单仅占整个表的一小部分,但这些行是访问次数最多的行,则可以通过仅在未开票行上创建索引来提高性能。创建索引的命令如下所示:
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 < 10000;
我很好奇,直接在billed字段上为不真实的部分创建索引不是更好吗,特别是对于尚未开票的订单?
CREATE INDEX orders_unbilled_index ON orders (billed)
WHERE billed is not true;
官方示例在 order_nr 字段上创建部分索引。这可能是什么原因?
部分索引的目标是拥有一个尽可能小的索引,在使用[非常]小的占用空间的同时回答许多业务问题。
你提到的索引没有太大意义:
CREATE INDEX orders_unbilled_index ON orders (billed)
WHERE billed is not true;
如果表有 100 万行,但其中只有 300 行未计费,那么该索引将只有 300 个条目(好!),并且所有条目将具有相同的值(坏!)。
索引的目标是具有不同的值,因此可以轻松搜索特定数据。您可以按客户名称、未偿金额、日期或订单号进行索引(如原始示例所示)。
例如,如果您的业务需求是大约 50 个最早的未开票订单,则以下索引可能会有所帮助:
CREATE INDEX orders_unbilled_index ON orders (creation_date)
WHERE billed is not true;
这几乎可以立即解决以下查询:
select * from orders where billed is not true order by creation_date limit 50;