为什么我的时间戳索引没有被 returns 200 条 3 亿条记录的查询使用

Why my timestamp index is not being used by a query that returns 200 of records of 300 million

我有一个table。

这是一个简单的 table,称为带有一些时间戳字段的事件。

CREATE TABLE public.event (
id int8 NOT NULL DEFAULT nextval('event_id_seq'::regclass),
email_id bpchar(36) NOT NULL,
sending timestamp NULL,
CONSTRAINT event_pkey PRIMARY KEY (id)
)
WITH (
   OIDS=FALSE
);

CREATE INDEX email_idx ON public.event (email_id);

CREATE INDEX sending_idx ON public.event ((sending::date));

这些时间戳字段之一称为发送,它具有日期索引。

问题是 postgres 正在使用 seqscan 检索以下查询的结果:

select email_id from event where sending between  '2018-01-07 00:33:00'  and '2018-01-07 00:33:20' 

我执行了解释分析,结果如下:

Seq Scan on event  (cost=0.00..11391171.08 rows=139 width=37) (actual time=265885.080..503636.060 rows=257 loops=1)
Filter: ((sending >= '2018-01-07 00:33:00'::timestamp without time zone) AND (sending <= '2018-01-07 00:33:20'::timestamp without time zone))
 Rows Removed by Filter: 317633116
Planning time: 0.066 ms
Execution time: 503650.634 ms

为什么 postgres 执行 seqscan 从索引字段的数百万条记录中检索几百条记录?

谢谢!

您没有索引 timestamp,您索引了 date。在您的 where 子句中,您还需要将列与日期进行比较以使索引可用。

将其与日期进行比较:

where sending between date '2018-01-07'  and date '2018-01-07' 

或在时间戳值上创建索引:

CREATE INDEX sending_idx ON public.event (sending);

那么您的原始查询应该使用索引。

不要忘记 analyze 您的 table 以更新您的统计信息;