【问题标题】:Mysql query, running slow when using ORDER BYMysql查询,使用ORDER BY时运行缓慢
【发布时间】:2021-04-22 15:14:09
【问题描述】:

使用 ORDER BY 子句时,我的查询运行缓慢。

具有最大行数的表,包括大约。 30.000 行。

结果是 10 行,大约需要 0.2 秒。

如果没有“ORDER BY id DESC”,则需要 0.01 秒。

我查看了堆栈上的其他帖子并尝试优化此脚本,但我的知识已达到极限。

我还为所有列连接、WHERE、ORDER by 创建了索引。

您有什么可以改进的地方,或者关于如何通过返回更快的结果来下订单的想法?

Mysql 是这样的

SELECT  *
    FROM  
        ( SELECT  posts.id, posts.createdDateTime, posts.caption, posts.postUrl,
                posts.isVideo, posts.paymentType, posts.postPrice, profile.name,
                profile.username, 
                ( SELECT  COUNT(*)
                    FROM  likes
                    where  likes.postIdFK=posts.id
                ) as likes, 
                ( SELECT  COUNT(*)
                    FROM  likes
                    where  likes.postIdFK=posts.id
                      AND  likes.userIdFK=21643
                ) as myLike, 
                ( SELECT  COUNT(*)
                    FROM  comments
                    where  comments.postIdFK=posts.id
                      AND  comments.deleted=0
                ) as comments
            FROM  posts
            JOIN  users AS profile  ON posts.userIdFK=profile.id
            WHERE  posts.deleted=0
              AND  profile.deleted=0
              AND  ( posts.userIdFK IN (
                        SELECT  subscribedToProfileIdFK
                            FROM  
                                ( SELECT  userSubscriptions.subscribedToProfileIdFK, max(monthlySubscriptions.endSubscription) endSubscription
                                    FROM  userSubscriptions
                                    LEFT JOIN  monthlySubscriptions  ON monthlySubscriptions.userSubscriptionId=userSubscriptions.id
                                    WHERE  userSubscriptions.userIdFK=21643
                                      AND  userSubscriptions.quickpayComplete=1
                                    GROUP BY  userSubscriptions.id 
                          ) t
                            WHERE  (t.endSubscription >= CURDATE())
                            GROUP BY  t.subscribedToProfileIdFK )
                      OR  posts.id IN (
                        SELECT  paidPosts.postIdFK
                            FROM  paidPosts
                            WHERE  paidPosts.userIdFK=21643 
                          )
                      OR  posts.userIDFK=21643 ) 
        ) AS row
    ORDER BY  id DESC
    LIMIT  0,10

解释看起来像这样

id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY profile ref PRIMARY,deleted deleted 1 const 5410 Using temporary; Using filesort
1 PRIMARY posts ref userIdFK,deleted userIdFK 4 admin_slc.profile.id 1 Using where
8 MATERIALIZED paidPosts ALL userIdFK,postIdFK NULL NULL NULL 5 Using where
6 MATERIALIZED ALL NULL NULL NULL NULL 14 Using where
7 DERIVED userSubscriptions index userIdFK, quickpayComplete PRIMARY 4 NULL 15 Using where
7 DERIVED monthlySubscriptions ref userSubscriptionId userSubscriptionId 4 admin_slc.userSubscriptions.id 1
5 DEPENDENT SUBQUERY comments ref postIdFK,deleted postIdFK 4 admin_slc.posts.id 1 Using where
4 DEPENDENT SUBQUERY likes ref userIdFK,postIdFK postIdFK 4 admin_slc.posts.id 1 Using where
3 DEPENDENT SUBQUERY likes ref postIdFK postIdFK 4 admin_slc.posts.id 1 Using index

如果您需要表定义,请告诉我。

//谢谢

【问题讨论】:

  • 请提供SHOW CREATE TABLE likes;

标签: mysql sql performance join query-optimization


【解决方案1】:

您绝对可以重写此查询以从 SELECT 子句中删除选择查询,如下所示:

SELECT * FROM ( 
    SELECT posts.id, 
           posts.createdDateTime,  
           posts.caption,  
           posts.postUrl,  
           posts.isVideo,  
           posts.paymentType,  
           posts.postPrice, 
           profile.name,  
           profile.username,
           l.cnt as likes,
           ml.cnt as myLike,
           comm.cnt as comments -- as comments
    FROM posts 
    JOIN users AS profile ON posts.userIdFK=profile.id
    LEFT JOIN (SELECT likes.postIdFK, COUNT(*) as cnt FROM likes group by likes.postIdFK) as l 
      on l.postIdFK=posts.id
    LEFT JOIN (SELECT likes.postIdFK, COUNT(*) as cnt FROM likes where likes.userIdFK=21643 group by likes.postIdFK) ml 
      on ml.postIdFK=posts.id
    LEFT JOIN (SELECT comments.postIdFK, COUNT(*) as cnt FROM comments where comments.deleted=0 group by comments.postIdFK) as comm 
       on comm.postIdFK=posts.id
    WHERE posts.deleted=0 
    AND profile.deleted=0
    AND ( posts.userIdFK IN (
            SELECT subscribedToProfileIdFK 
              FROM (SELECT userSubscriptions.subscribedToProfileIdFK,
                           max(monthlySubscriptions.endSubscription) endSubscription
                      FROM userSubscriptions 
                      LEFT JOIN monthlySubscriptions ON monthlySubscriptions.userSubscriptionId=userSubscriptions.id 
                     WHERE userSubscriptions.userIdFK=21643 
                       AND userSubscriptions.quickpayComplete=1
                     GROUP BY userSubscriptions.id) t
            WHERE (t.endSubscription >= CURDATE())
           -- GROUP BY t.subscribedToProfileIdFK -- this group by is not needed
           )
        OR exists 
           (SELECT 1 
              FROM paidPosts 
             WHERE paidPosts.userIdFK=21643
               AND posts.id = paidPosts.postIdFK)
        OR posts.userIDFK=21643 
     )
) AS row
ORDER BY id DESC
LIMIT 0,10

【讨论】:

  • 哇,好多了!谢谢
猜你喜欢
  • 2020-05-15
  • 1970-01-01
  • 2021-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 2019-08-21
相关资源
最近更新 更多