我正在try 使用表上的复合(多列)索引来帮助创建每日报告计数.我使用的是Postgres 13,我的表格如下所示:
CREATE TABLE inquiries (
id bigint NOT NULL,
identity_id bigint NOT NULL,
received_at timestamp(0) without time zone NOT NULL,
purpose_id bigint NOT NULL,
location_id bigint NOT NULL
);
CREATE INDEX "inquiries_DATE_index" ON inquiries USING btree
(date(received_at), location_id, purpose_id, identity_id);
我的查询看起来像这样:
SELECT DATE(received_at), location_id, purpose_id, COUNT(DISTINCT identity_id)
FROM inquiries
WHERE (DATE(received_at) >= $1)
AND (DATE(received_at) <= $2)
GROUP BY 1, 2, 3
解释输出如下所示:
GroupAggregate (cost=43703.28..45785.49 rows=10950 width=19)
Group Key: (date(received_at)), location_id, purpose_id
-> Sort (cost=43703.28..44092.34 rows=155627 width=16)
Sort Key: (date(received_at)), location_id, purpose_id
-> Bitmap Heap Scan on inquiries (cost=5243.60..27622.21 rows=155627 width=16)
Recheck Cond: ((date(received_at) >= '2023-11-01'::date) AND (date(received_at) <= '2023-11-30'::date))
-> Bitmap Index Scan on "inquiries_DATE_index" (cost=0.00..5204.70 rows=155627 width=0)
Index Cond: ((date(received_at) >= '2023-11-01'::date) AND (date(received_at) <= '2023-11-30'::date))
索引似乎没有帮助,执行查询需要很长时间.如果我向表中添加一个日期列,并使用该列而不是date(received_at)
,则查询会更好地工作,并且查询计划更改为:
GroupAggregate (cost=0.43..85199.58 rows=10980 width=19)
Group Key: pacific_date, location_id, purpose_id
-> Index Only Scan using inquiries_pacific_date_index on inquiries (cost=0.43..77813.12 rows=727666 width=16)
Index Cond: ((pacific_date >= '2023-11-01'::date) AND (pacific_date <= '2023-11-30'::date))
如果我找不到更好的方法,我想我可以这样做,但这似乎是多余的.有没有一种方法可以编写我的原始查询,使其更好地利用索引?