【发布时间】:2021-06-11 00:26:30
【问题描述】:
我有以下问题
select * from activity_feed where user_id in (select following_id from user_follow where follower_id=:user_id)
union
select * from activity_feed where project_id in (select project_id from user_project_follow where user_id=:user_id)
order by id desc limit 30
根据 postico 大约需要 14 毫秒
但是当我在此查询上执行explain analyze 时,计划时间为 0.5 毫秒,执行时间约为 800 毫秒(这是我实际期望的)。这是因为没有explain analyze 的查询正在返回缓存结果吗?即使在这种情况下,我仍然得到不到 20 毫秒的结果。使用其他值。
哪一个更能说明我将在生产中获得的性能?我还意识到这是一个相当低效的查询,我似乎无法找出一个可以提高效率的索引。我可能不得不不使用union
编辑:执行计划
Limit (cost=1380.94..1380.96 rows=10 width=148) (actual time=771.111..771.405 rows=10 loops=1)
-> Sort (cost=1380.94..1385.64 rows=1881 width=148) (actual time=771.097..771.160 rows=10 loops=1)
Sort Key: activity_feed."timestamp" DESC
Sort Method: top-N heapsort Memory: 27kB
-> HashAggregate (cost=1321.48..1340.29 rows=1881 width=148) (actual time=714.888..743.273 rows=4462 loops=1)
Group Key: activity_feed.id, activity_feed."timestamp", activity_feed.user_id, activity_feed.verb, activity_feed.object_type, activity_feed.object_id, activity_feed.project_id, activity_feed.privacy_level, activity_feed.local_time, activity_feed.local_date
-> Append (cost=5.12..1274.46 rows=1881 width=148) (actual time=0.998..682.466 rows=4487 loops=1)
-> Hash Join (cost=5.12..610.43 rows=1350 width=70) (actual time=0.982..326.089 rows=3013 loops=1)
Hash Cond: (activity_feed.user_id = user_follow.following_id)
-> Seq Scan on activity_feed (cost=0.00..541.15 rows=24215 width=70) (actual time=0.016..150.535 rows=24215 loops=1)
-> Hash (cost=4.78..4.78 rows=28 width=8) (actual time=0.911..0.922 rows=29 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 10kB
-> Index Only Scan using unique_user_follow_pair on user_follow (cost=0.29..4.78 rows=28 width=8) (actual time=0.022..0.334 rows=29 loops=1)
Index Cond: (follower_id = '17420532762804570'::bigint)
Heap Fetches: 0
-> Hash Join (cost=30.50..635.81 rows=531 width=70) (actual time=0.351..301.945 rows=1474 loops=1)
Hash Cond: (activity_feed_1.project_id = user_project_follow.project_id)
-> Seq Scan on activity_feed activity_feed_1 (cost=0.00..541.15 rows=24215 width=70) (actual time=0.027..143.896 rows=24215 loops=1)
-> Hash (cost=30.36..30.36 rows=11 width=8) (actual time=0.171..0.182 rows=11 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
-> Index Only Scan using idx_user_project_follow_temp on user_project_follow (cost=0.28..30.36 rows=11 width=8) (actual time=0.020..0.102 rows=11 loops=1)
Index Cond: (user_id = '17420532762804570'::bigint)
Heap Fetches: 11
Planning Time: 0.571 ms
Execution Time: 771.774 ms
提前感谢您的帮助!
【问题讨论】:
-
不太可能产生如此大的差异,但
EXPLAIN (ANALYZE)完成的所有时钟调用都会减慢它的速度。如果你这样做EXPLAIN (ANALYZE, TIMING OFF)会发生什么? -
请出示计划。
-
也许 psql 和 postico 使用了不同的设置,这使得计划不同(比如 postico 可能将其隐式包装在游标中)。能否让 postico 本身向您展示执行计划?
-
@jjanes 将计划添加到问题中。另外,您说得对,EXPLAIN (ANALYZE, TIMING OFF) 实际上确实将其降低到了 9 毫秒。我认为如果桌子变大,最终
union将证明效率太低,但这是另一天的担忧
标签: sql postgresql indexing query-optimization sql-execution-plan