Esta consulta é muito lenta:
EXPLAIN (ANALYZE, buffers) SELECT *
FROM
"Follows" AS "Follow"
INNER JOIN "Users" AS "followee" ON "Follow"."followeeId" = "followee"."id"
WHERE
"Follow"."followerId" = 169368
ORDER BY
"Follow"."createdAt" DESC
LIMIT 1000;
Aqui está a explicação:
Limit (cost=0.86..2120.08 rows=141 width=814) (actual time=0.776..239.289 rows=262 loops=1)
Buffers: shared hit=750 read=673 dirtied=1
-> Nested Loop (cost=0.86..2120.08 rows=141 width=814) (actual time=0.774..239.148 rows=262 loops=1)
Buffers: shared hit=750 read=673 dirtied=1
-> Index Scan using follows_followinglist_followerid_createdat_idx on "Follows" "Follow" (cost=0.43..681.88 rows=170 width=41) (actual time=0.377..52.687 rows=262 loops=1)
Index Cond: ("followerId" = 169368)
Buffers: shared hit=149 read=115
-> Index Scan using "Users_pkey" on "Users" followee (cost=0.43..8.45 rows=1 width=773) (actual time=0.559..0.709 rows=1 loops=262)
Index Cond: (id = "Follow"."followeeId")
Buffers: shared hit=601 read=558 dirtied=1
Total runtime: 239.545 ms
Eu tenho os seguintes índices (atualmente, ele está usando o primeiro):
CREATE INDEX follows_followinglist_followerid_createdat_idx ON "Follows"
("followerId", "createdAt" DESC)
CREATE INDEX follows_followinglist_followerid_createdat_idx2 ON "Follows"
("createdAt" DESC, "followerId")
CREATE INDEX follows_followerId_fk_index ON "Follows" ("followerId");
CREATE INDEX "follows_createdat_index" ON "public"."Follows" USING btree("createdAt" DESC);
Antes de adicionar os dois primeiros, o custo era um pouco menor (~ 2.000) usando follows_followerId_fk_index
, mas ainda muito lento.
Eu estou querendo saber se há uma maneira de otimizar isso ainda mais.
Consulta simplificada para torná-la legível:
Seu índice
follows_followinglist_followerid_createdat_idx
parece bom para o trabalho. No Postgres 9.2+, pode ficar um pouco mais rápido se você acrescentar "followeeId" ao índice - se e somente se você puder obter uma varredura somente de índice com isso. Talvez não seja possível no seu caso.Geralmente, essa consulta não será rápida, pois você precisa buscar até 1000 linhas aleatórias de
"Users"
. A chave para o desempenho será:"Users"
for grande.Também ajudaria a agrupar a
"Follows"
mesa de tempos em tempos. Detalhes: