我在本地(OS X)执行了不同的查询,在同一个DB上使用Heroku执行查询,相同的PG版本为9.4.5。
我运行ANALYZE来更新Heroku和本地(在最近的转储上)所有两个涉及的表的统计信息。
查询:
SELECT "likes"."post_id" AS post_id
FROM likes
INNER JOIN "follows" on "follows"."followee_id" = "likes"."user_id"
WHERE "follows"."follower_id" = 1416077
ORDER BY "likes"."id" DESC ;
喜欢的索引:
"likes_pkey" PRIMARY KEY, btree (id)
"likes_post_id_user_id_key" UNIQUE CONSTRAINT, btree (user_id, post_id)
"index_likes_on_created_at" btree (created_at)
"index_likes_on_post_id" btree (post_id)
索引如下:
"follows_pkey" PRIMARY KEY, btree (id)
"follows_follower_id_followee_id_key" UNIQUE CONSTRAINT, btree (follower_id, followee_id)
"index_follows_on_followee_id" btree (followee_id)
pg_settings中的 enable_*
设置是相同的。
work_mem
是相同的
seq_page_cost = 1
random_page_cost
= 4,Heroku上为2,但在heroku上将其设置为4并不会改变任何内容
explain(analyze, verbose)
本地
Sort (cost=2611609.82..2631198.92 rows=7835638 width=8) (actual time=177.588..190.331 rows=96766 loops=1)
Output: likes.post_id, likes.id
Sort Key: likes.id
Sort Method: external merge Disk: 1704kB
-> Nested Loop (cost=1.00..1500109.83 rows=7835638 width=8) (actual time=0.050..129.308 rows=96766 loops=1)
Output: likes.post_id, likes.id
-> Index Only Scan using follows_follower_id_followee_id_key on public.follows (cost=0.44..1253.60 rows=435 width=4) (actual time=0.029..0.074 rows=16 loops=1)
Output: follows.follower_id, follows.followee_id
Index Cond: (follows.follower_id = 1416077)
Heap Fetches: 16
-> Index Scan using likes_post_id_user_id_key on public.likes (cost=0.56..3405.71 rows=3994 width=12) (actual time=0.011..7.258 rows=6048 loops=16)
Output: likes.id, likes.user_id, likes.post_id, likes.created_at
Index Cond: (likes.user_id = follows.followee_id)
Planning time: 0.500 ms
Execution time: 200.648 ms
Heroku上的 explain(analyze, verbose)
:
Sort (cost=1532085.93..1536475.21 rows=8778573 width=8) (actual time=52403.641..52413.461 rows=96763 loops=1)
Output: likes.post_id, likes.id
Sort Key: likes.id
Sort Method: quicksort Memory: 7608kB
-> Hash Join (cost=926122.23..1243873.27 rows=8778573 width=8) (actual time=40392.996..52357.989 rows=96763 loops=1)
Output: likes.post_id, likes.id
Hash Cond: (follows.followee_id = likes.user_id)
-> Index Only Scan using follows_follower_id_followee_id_key on public.follows (cost=0.09..9.69 rows=490 width=4) (actual time=0.048..0.086 rows=16 loops=1)
Output: follows.followee_id
Index Cond: (follows.follower_id = 1416077)
Heap Fetches: 0
-> Hash (cost=516037.68..516037.68 rows=48919560 width=12) (actual time=40392.575..40392.575 rows=48932091 loops=1)
Output: likes.post_id, likes.id, likes.user_id
Buckets: 65536 Batches: 256 (originally 128) Memory Usage: 30721kB
-> Seq Scan on public.likes (cost=0.00..516037.68 rows=48919560 width=12) (actual time=0.013..18437.681 rows=48932091 loops=1)
Output: likes.post_id, likes.id, likes.user_id
Planning time: 0.713 ms
Execution time: 52434.805 ms
为什么这些执行计划有所不同?我应该如何调整Heroku以使其在本地工作?