出于某种原因,Postgres没有使用我定义的索引 - 我可能会遗漏一些显而易见的东西,但是我已经在墙上撞了一会儿并且非常喜欢你的建议。
表格定义:
CREATE TABLE "public"."useractivity" (
"id" int4 NOT NULL DEFAULT nextval('useractivity_id_seq'::regclass),
"userid" int8 NOT NULL,
"created_at" timestamp(6) NOT NULL DEFAULT now(),
"channel" varchar(32) NOT NULL COLLATE "default",
"action" varchar(64) NOT NULL COLLATE "default",
"details" varchar(256) COLLATE "default",
CONSTRAINT "useractivity_pkey" PRIMARY KEY ("id") NOT DEFERRABLE INITIALLY IMMEDIATE,
CONSTRAINT "action_user_fk" FOREIGN KEY ("userid") REFERENCES "public"."user" ("id") ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE)
WITH (OIDS=FALSE);
CREATE INDEX "activity_user_idx" ON "public"."useractivity" USING btree(userid ASC NULLS LAST);
CREATE INDEX "idx_useractivity_action" ON "public"."useractivity" USING btree(userid ASC NULLS LAST, "action" COLLATE "default" ASC NULLS LAST);
CREATE INDEX "idx_useractivity_action2" ON "public"."useractivity" USING btree("action" COLLATE "default" ASC NULLS LAST, userid ASC NULLS LAST);
CREATE INDEX "idx_useractivity_action_date" ON "public"."useractivity" USING btree(userid ASC NULLS LAST, created_at ASC NULLS LAST);
查询:
SELECT useractivity.userid,
count(*) AS num
FROM useractivity
WHERE (useractivity.action= 'sent')
GROUP BY useractivity.userid
查询的EXPLAIN输出:
HashAggregate (cost=15846.78..15880.29 rows=3351 width=8)
-> Seq Scan on useractivity (cost=0.00..14987.83 rows=171791 width=8)
Filter: ((action)::text = 'sent'::text)
为什么Postgres没有采用任何索引,而是对171,000行进行序列扫描?