【发布时间】:2021-10-28 22:40:42
【问题描述】:
我发现有时响应缓慢的查询正在查看执行(解释分析)计划。
我觉得子查询的join部分比较慢,但是看执行计划,我觉得问题是循环很多。
这是查询:
LOG: execute <unnamed>:
SELECT *,
(SELECT COUNT(messaging_channelmembership.id)
FROM messaging_channelmembership
INNER JOIN messaging_member
ON (messaging_channelmembership.member_id = messaging_member.id)
INNER JOIN messaging_user
ON (messaging_member.user_id = messaging_user.id)
WHERE (messaging_channelmembership.channel_id = messaging_message.channel_id
AND messaging_channelmembership.last_read_message < messaging_message.id
AND messaging_user.is_bot = false
AND messaging_user.username != 'puddlrbot'
AND messaging_channelmembership.member_id != messaging_message.sender_id)
) as unread_count
FROM "messaging_message"
WHERE ("messaging_message"."channel_id" = $1)
AND (messaging_message.id >= $2)
ORDER BY messaging_message.created
LIMIT 30;
解释分析
Limit (cost=169.00..169.00 rows=1 width=101) (actual time=218.212..218.218 rows=30 loops=1)
-> Sort (cost=169.00..169.00 rows=1 width=101) (actual time=218.211..218.213 rows=30 loops=1)
Sort Key: messaging_message.created
Sort Method: top-N heapsort Memory: 32kB
-> Bitmap Heap Scan on messaging_message (cost=105.15..168.99 rows=1 width=101) (actual time=0.898..217.929 rows=369 loops=1)
Recheck Cond: ((channel_id = 1) AND (id >= 235589605))
Heap Blocks: exact=12
-> BitmapAnd (cost=105.15..105.15 rows=1 width=0) (actual time=0.371..0.371 rows=0 loops=1)
-> Bitmap Index Scan on messaging_message_72eb6c85 (cost=0.00..32.53 rows=1596 width=0) (actual time=0.163..0.163 rows=2078 loops=1)
Index Cond: (channel_id = 1)
-> Bitmap Index Scan on messaging_message_pkey (cost=0.00..72.37 rows=3707 width=0) (actual time=0.142..0.142 rows=3066 loops=1)
Index Cond: (id >= 235589605)
SubPlan 1
-> Aggregate (cost=59.81..59.82 rows=1 width=4) (actual time=0.588..0.588 rows=1 loops=369)
-> Nested Loop (cost=1.27..59.80 rows=3 width=4) (actual time=0.008..0.578 rows=87 loops=369)
-> Nested Loop (cost=0.85..57.62 rows=3 width=8) (actual time=0.006..0.359 rows=87 loops=369)
-> Index Scan using messaging_channelmembership_72eb6c85 on messaging_channelmembership (cost=0.42..32.27 rows=3 width=8) (actual time=0.004..0.051 rows=87 loops=369)
Index Cond: (channel_id = messaging_message.channel_id)
Filter: ((last_read_message < messaging_message.id) AND (member_id <> messaging_message.sender_id))
Rows Removed by Filter: 3
-> Index Scan using messaging_member_pkey on messaging_member (cost=0.42..8.44 rows=1 width=8) (actual time=0.003..0.003 rows=1 loops=32016)
Index Cond: (id = messaging_channelmembership.member_id)
-> Index Scan using messaging_user_pkey on messaging_user (cost=0.42..0.72 rows=1 width=4) (actual time=0.002..0.002 rows=1 loops=32016)
Index Cond: (id = messaging_member.user_id)
Filter: ((NOT is_bot) AND ((username)::text <> 'puddlrbot'::text))
Planning time: 0.462 ms
Execution time: 218.258 ms
【问题讨论】:
-
尝试将子查询重写为外连接,这样就可以获得比嵌套循环执行得更好的东西。
-
如果可能,最好将相关子查询转换为子查询。
-
你使用的是什么版本的 PostgreSQL?
标签: sql postgresql indexing sql-execution-plan