Query:
EXPLAIN (ANALYZE, BUFFERS) SELECT
COUNT (*) AS "count"
FROM
"Posts" AS "Post"
WHERE
"Post"."createdAt" > '2015-08-19 14:55:50.398'
AND "Post"."new" = TRUE;
Index:
CREATE INDEX posts_new_createdat_idx ON "Posts" ("createdAt")
WHERE
NEW = TRUE
Plan:
Aggregate (cost=389915.59..389915.60 rows=1 width=0) (actual time=4234.772..4234.773 rows=1 loops=1)
Buffers: shared hit=254427
-> Bitmap Heap Scan on "Posts" "Post" (cost=14415.81..387990.63 rows=769985 width=0) (actual time=123.805..3859.150 rows=1138854 loops=1)
Recheck Cond: (("createdAt" > '2015-08-19 14:55:50.398+00'::timestamp with time zone) AND new)
Rows Removed by Index Recheck: 8238790
Buffers: shared hit=254427
-> Bitmap Index Scan on posts_new_createdat_idx (cost=0.00..14223.32 rows=769985 width=0) (actual time=122.601..122.601 rows=1138854 loops=1)
Index Cond: ("createdAt" > '2015-08-19 14:55:50.398+00'::timestamp with time zone)
Buffers: shared hit=3114
Total runtime: 4234.989 ms
Schema:
CREATE TABLE "public"."Posts" (
"id" int4 NOT NULL DEFAULT nextval('"Posts_id_seq"'::regclass),
"actionId" int4,
"commentCount" int4 DEFAULT 0,
"facebook" bool,
"featurePostOnDate" timestamp(6) WITH TIME ZONE,
"forcedPrivate" bool,
"instagram" bool,
"isReported" bool,
"likeCount" int4 DEFAULT 0,
"note" text COLLATE "default",
"photo" varchar(255) COLLATE "default",
"private" bool,
"new" bool,
"popular" bool,
"twitter" bool,
"userId" int4,
"objectId" varchar(255) COLLATE "default",
"createdAt" timestamp(6) WITH TIME ZONE,
"updatedAt" timestamp(6) WITH TIME ZONE,
"activityLogId" int4,
"weightLogId" int4,
"workoutId" int4,
"workoutLogId" int4,
"thumbnail" varchar(255) COLLATE "default"
)
Data:
new = true
for 99% or records- Any posts older than 2 weeks can be ignored (from the count and the index)
Database Details:
Host = Amazon AWS
Engine = PostgreSQL 9.3.10
Instance Class = db.r3.8xlarge
Storage Type = SSD
IOPS = 3000
StorageAmount = 500 GB
As you can see, the partial index is very large. Is there a way to better index so that the recheck condition is not so heavy?