首页 > 解决方案 > Postgres - 读取日期之前或之后的日期索引 (<, <=, >, >=)

问题描述

当我的状况在给定日期之前或之后时,我的日期索引有问题。使用运算符(<、<=、>、>=)。

我的桌子看起来像这样

CREATE TABLE date_playground
(
  id          BIGSERIAL   NOT NULL,
  due_date    date        NOT NULL,

  primary key (id)
);

我的索引是

CREATE INDEX date_playground_idx_due_date
ON date_playground (due_date);

当我的查询是

-- SAMPLE  1 
EXPLAIN ANALYZE SELECT
  *
FROM  date_playground
WHERE due_date = '2019-09-07' :: DATE;

这使用索引

QUERY PLAN
Index Scan using date_playground_idx_due_date on date_playground  (cost=0.42..279.73 rows=75 width=287) (actual time=0.043..0.071 rows=10 loops=1)
  Index Cond: (due_date = '2019-09-07'::date)
Planning Time: 0.636 ms
Execution Time: 0.140 ms

但是,当我使用指定的运算符时 - <、<=、>、>=

-- SAMPLE 2
EXPLAIN ANALYZE SELECT
  *
FROM  ln.amortization_schedule_active a
WHERE due_date <= '2019-09-07' :: DATE;

QUERY PLAN
Seq Scan on date_playground  (cost=0.00..35133.86 rows=396944 width=287) (actual time=0.032..443.417 rows=404839 loops=1)
  Filter: (due_date <= '2019-09-07'::date)
  Rows Removed by Filter: 331870
Planning Time: 0.437 ms
Execution Time: 483.891 ms

它从不使用索引,它总是执行完整扫描。

谁能建议我如何优化第二个查询?

谢谢!

标签: postgresqlindexing

解决方案


PostgreSQL可以在您的第二个查询中使用该索引,但它正确地选择不这样做,因为它效率低下。

对于选择表中一半行的查询,顺序扫描比索引扫描更有效:索引扫描无论如何都必须访问大部分表块,那么为什么还要麻烦随机 I/O 或构建位图呢?


推荐阅读