想问一个 sql 语句该如何优化?

select fc.* from cq_friend_circle as fc 
                where
                  -- 获取:好友的朋友圈
                    fc.user_id in (1,2,3,4,5)
                    and
                    (
                            -- 获取:当前用户为朋友圈发布者
                            fc.user_id = 1 
                            or
                            (
                                    -- 朋友圈开放程度限制
                                    (
                                            -- 获取:朋友圈被设置为公开,
                                            fc.open_level = 'public' 
                                            or
                                            (
                                                    -- 获取:朋友圈被设置为仅自己可见,当前用户即朋友圈发布者
                                                    fc.open_level = 'self' 
                                                    and 
                                                    fc.user_id = 1
                                            ) 
                                            or 
                                            (
                                                    -- 获取:朋友圈被设置为指定分组可见,且当前用户存在于其中
                                                    fc.open_level = 'assign' 
                                                    and 
                                                                                                        (
                                                                                                                (
                                                                                                                        select count(id) from cq_friend_circle_group_member where 
                                                                                                                                user_id = 1 
                                                                                                                                and 
                                                                                                                                friend_circle_group_id in (select friend_circle_group_id from cq_friend_circle_visible where friend_circle_id = fc.id)
                                                                                                                ) > 0
                                                                                                        )
                                            )
                                    )
                                    and 
                                    -- 好友权限限制
                                    (
                                            (
                                                    -- 获取:你没有对好友好友设置权限/好友没有对你设置权限
                                                    (select count(id) from cq_friend_privilege where user_id = 1 and friend_id = fc.user_id) = 0
                                                    and
                                                    (select count(id) from cq_friend_privilege where user_id = fc.user_id and friend_id = 1) = 0
                                            )
                                            or
                                            (
                                                    -- 存在权限设置,根据设置值做进一步判断
                                                    (select count(id) from cq_friend_privilege where user_id = 1 and friend_id = fc.user_id) > 0
                                                    and
                                                    -- 权限设置值 shield != 0,当前登录用户没有设置不看他的朋友圈
                                                    (select shield from cq_friend_privilege where user_id = 1 and friend_id = fc.user_id) != 1
                                                    and
                                                    (
                                                            -- 获取:好友没有对你设置权限
                                                            (select count(id) from cq_friend_privilege where user_id = fc.user_id and friend_id = 1) = 0
                                                                                                                        or
                                                                                                                        (
                                                                                                                                -- 获取:好友对你设置了权限,hidden != 1 ,好友朋友圈没有设置屏蔽当前登录用户
                                                                                                                                (select count(id) from cq_friend_privilege where user_id = fc.user_id and friend_id = 1) > 0
                                                                                                                                and
                                                                                                                                (select hidden from cq_friend_privilege where user_id = fc.user_id and friend_id = 1) != 1
                                                                                                                        )
                                                    )
                                            )
                                    )
                            )
                    )
                    order by
                    fc.create_time desc ,
                    fc.id desc
                    limit 0 , 10;

这个语句该如何优化?现在查询速度很慢,运行要近 1s+,这还是没有什么数据的情况下。

阅读 3.1k
6 个回答

条件的 (select count(id) from ..) > 0 这种语句要换成 exist( select * from ...)
(select count(id) from ..) = 0 换成 notExist( select * from ...)

建议主要还是针对业务进行优化

建议拆成多个小句子...
先不说一个句子逻辑太复杂方不方便维护,可mysql对子查询的支持比你想象中的烂很多...

建议题主将嵌套查询拿出来做联接查询,这样效率会高一点点

还是拆分为小语句,然后在代码中进行逻辑处理,你这样写 mysql会哭的

建议拆分为小语句,将条件的处理 在代码里面过滤,再进行主查询

够复杂的,exists 然后用explain 分析下,还是拆吧,拆小子句先查询,先查询的子句 还可以缓存

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题