PieCloudDB页面推荐SQL查询性能优化求助
性能优化建议
针对你的页面推荐SQL查询,以下是几个关键优化方向,能显著提升大数据量下的执行效率:
1. 替换UNION为UNION ALL,避免不必要的去重
原查询里用UNION生成双向好友关系,UNION会自动对结果排序去重,但Friendship表通常不会存在重复的反向好友记录(比如不会同时存(A,B)和(B,A)),改用UNION ALL可以跳过排序去重的开销,大幅提升子查询的执行速度:
SELECT user1_id, user2_id FROM Friendship UNION ALL SELECT user2_id, user1_id FROM Friendship
2. 移除多余的DISTINCT
你的查询已经通过GROUP BY f.user1_id, l.page_id完成了分组聚合,DISTINCT是完全多余的,去掉它可以减少数据库的额外计算步骤。
3. 用NOT EXISTS替代NOT IN的相关子查询
原WHERE子句中的NOT IN是相关子查询,会对每一行数据单独执行一次子查询,数据量大时开销极大。换成NOT EXISTS的写法,数据库能更高效地利用索引做关联过滤:
WHERE NOT EXISTS ( SELECT 1 FROM likes l2 WHERE l2.user_id = f.user1_id AND l2.page_id = l.page_id )
相比NOT IN,NOT EXISTS在处理NULL值时逻辑更严谨,且PieCloudDB对NOT EXISTS的执行计划优化更友好。
4. 添加合适的索引,加速关联与过滤
给以下字段添加索引,能让数据库快速定位数据,避免全表扫描:
- 给
Friendship表添加联合索引:(user1_id, user2_id),同时可以再建一个反向的(user2_id, user1_id),用来加速反向好友关系的查询。 - 给
likes表添加联合索引:(user_id, page_id),这个索引能同时满足子查询的过滤和主查询的关联需求;另外可以补充一个(user_id)的单键索引,加速主查询中f.user2_id = l.user_id的关联。
5. 优化后的完整SQL
整合以上优化点后的最终查询如下:
SELECT f.user1_id AS user_id, l.page_id, COUNT(*) AS likes_numbers FROM ( SELECT user1_id, user2_id FROM Friendship UNION ALL SELECT user2_id, user1_id FROM Friendship ) f JOIN likes l ON f.user2_id = l.user_id WHERE NOT EXISTS ( SELECT 1 FROM likes l2 WHERE l2.user_id = f.user1_id AND l2.page_id = l.page_id ) GROUP BY f.user1_id, l.page_id
额外建议
如果Friendship表数据量特别大,可以考虑预先计算并存储双向好友关系(比如通过定时任务同步生成一张双向好友表),避免每次查询都执行UNION ALL的计算,进一步提升查询速度。
内容的提问来源于stack exchange,提问作者heihei Li
相关产品推荐
相关产品推荐

