我在Postgres中比较正常索引和部分索引的性能,令我惊讶的是,与正常索引相比,部分索引的性能似乎不是最优的.

创建索引后的EXPLAIN语句:

CREATE INDEX sett_ked_ped_idx ON public.settlement USING btree (client_id, is_deleted, knowledge_end_date DESC, period_end_date)

SELECT "settlement"."payee_email_id"
FROM "settlement"
WHERE ("settlement"."client_id" = 3
       AND NOT "settlement"."is_deleted"
       AND "settlement"."knowledge_end_date" IS NULL
       AND "settlement"."period_end_date" = '2023-06-30T23:59:59.999999+00:00'::timestamptz);

INDEX Scan USING sett_ked_ped_idx ON settlement (cost=0.56..7169.58 ROWS=3014 width=28) (actual TIME=1.485..2.284 ROWS=42 loops=1)

查询已执行,但希望try 部分索引,因为字段is_deletedknowledge_end_date将具有相同的值,并且作为部分索引可以减小整体索引大小.令我惊讶的是,随着时间和成本的增加,查询的性能变差了.

创建部分索引后的EXPLAIN语句:


CREATE INDEX sett_ked_ped_idx ON public.settlement USING btree (client_id, is_deleted, knowledge_end_date DESC, period_end_date) where not is_deleted and knowledge_end_date is null

INDEX Scan USING sett_ked_ped_idx ON settlement (cost=0.56..331556.57 ROWS=736 width=28) (actual TIME=602.011..1078.219 ROWS=42 loops=1)

我不知道为什么会是这样.使用部分索引的查询不应该更快吗?

推荐答案

为了公平起见,从分部索引中删除现在多余的列is_deletedknowledge_end_date:

CREATE INDEX sett_ked_ped_idx ON public.settlement (client_id, period_end_date)
WHERE NOT is_deleted AND knowledge_end_date IS NULL;

然后再测试一次.

需要注意的是,部分索引通常只有在排除了相当一部分所有行的情况下才有意义.如果WHERE NOT is_deleted AND knowledge_end_date IS NULL只排除了几个百分点或更少,就不要go 那里.

Postgresql相关问答推荐

Select 二维数组中的特定元素PostgreSQL

将列类型从文本[]更改为jsonb[]

Gorm 创建表单数据文件上传错误

如何准确确定边界附近的点和地理的 ST_Intersects(ST_Intersects geography vs. Geometry diffrepancy)

postgres vacuum 是否改进了我的查询计划

Docker compose read connection reset by peer error on pipeline

使用 postgresql Select 整数作为位和状态表

Postgres 会话处于空闲状态,query = COMMIT 或 ROLLBACK

如何在 PostgreSQL 中截断日期?

如何查询存储在数组中的 Rails ActiveRecord 数据

Mac psql/readline - 未加载库

gem install pg 无法绑定到 libpq

在 postgresql 中将 bool 转换为 int

PostgreSQL 中跨多个表的索引

避免通过 JPA 将null值插入数据库表

使用 PostgreSQL 的 Linq To Sql

Postgres DB 上的整数超出范围

postgres LISTEN/NOTIFY rails

如何为本地 Rails 元素设置 Postgres 数据库?

PostgreSQL - 如何将数字字段中的秒数转换为 HH:MM:SS