我有一张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
我不确定索引发生了什么!
OFFSET
是bad for query performance。
原因是为了跳过前1000000行,数据库必须找到然后丢弃它们。因此,数据库的工作与省略OFFSET
子句的工作相同。
现在,对表的顺序扫描比索引扫描便宜,因此只有在检索到的行数远小于顺序扫描时,后者才有优势。在某些时候,查询计划将“倾斜”,PostgreSQL将假设索引扫描更便宜。你已经找到了这一点。
如果您的random_page_cost
设置正确反映了您的硬件,PostgreSQL将正确估计这一点。简而言之,PostgreSQL正在做正确的事情。