首页 > 解决方案 > Postgres查询不使用索引

问题描述

我有一张有 2000000 条记录的表。我有一个索引:

CREATE INDEX test
    ON public."PaymentReceipt" USING btree
    ("CompanyID" DESC NULLS LAST, created_at ASC NULLS LAST)
    TABLESPACE pg_default;

如果我运行此查询,它将运行索引:

explain 
select * 
from public."PaymentReceipt" 
where "CompanyID" = '5c67762bd0949' 
order by "created_at" desc 
limit 100 offset 1600589

但是如果我运行这个查询,它不会使用索引:

explain 
select * 
from public."PaymentReceipt" 
where "CompanyID" = '5c67762bd0949' 
order by "created_at" desc 
limit 100 offset 1600590

我不确定索引发生了什么!

标签: postgresqlquery-performance

解决方案


OFFSET对查询性能不利。

原因是为了跳过前 1000000 行,数据库必须找到然后丢弃它们。因此,数据库的工作与省略该OFFSET子句相同。

现在,表的顺序扫描比索引扫描便宜,因此后者只有在检索的行数比顺序扫描少得多的情况下才有优势。在某些时候,查询计划会“倾斜”,而 PostgreSQL 会假设索引扫描更便宜。你已经找到了这一点。

如果您的random_page_cost设置正确地反映了您的硬件,PostgreSQL 将正确估计这一点。简而言之,PostgreSQL 正在做正确的事情。


推荐阅读