Mysql 使用多表优化查询

Mysql 使用多表优化查询,mysql,sql,Mysql,Sql,我有一个查询,其中数据来自多个表 SELECT iUserID, iUserID AS userID, (CASE vUSBG WHEN 1 THEN 'Yes' WHEN 0 THEN 'No' END) AS vUSBG, concat(vFirstname,' ',vLastname) AS Name, vEmail, eType, eStat

我有一个查询,其中数据来自多个表

SELECT iUserID,
       iUserID AS userID,
       (CASE vUSBG
            WHEN 1 THEN 'Yes'
            WHEN 0 THEN 'No'
        END) AS vUSBG,
       concat(vFirstname,' ',vLastname) AS Name,
       vEmail,
       eType,
       eStatus,
       tAddedDate,
       eExpert,
       eAdmin,

  (SELECT count(iUserID) AS total
   FROM tbl_friend
   WHERE iUserID = tbl_user.iUserID) AS count_f,

  (SELECT COUNT(*)
   FROM bar_followers
   WHERE bar_followers.iUserID = tbl_user.iUserID) AS bar_follows,

  (SELECT COUNT(b.iBrandID)
   FROM tbl_company_follow,
        tbl_brand b
   WHERE tbl_company_follow.iUserID = tbl_user.iUserID
     AND b.iCompanyID = tbl_company_follow.iCompanyID) AS brand_follows,

  (SELECT sum(points) AS totalpoints
   FROM tbl_points,
        tbl_post p
   WHERE iUserID = tbl_user.iUserID
     AND p.iPostID = tbl_points.post_id) AS countPoints
FROM tbl_user
此查询耗时
8.3595秒


如何缩短时间?

除了缺少明确的
join
语法外,您的查询是合理的

检查以确保您具有以下索引:

  • tbl\u friend(iUserId)
  • bar\u followers(iUserID)
  • tbl\u company\u follow(iUserID,iCompanyID)
  • tbl\u品牌(iCompanyID)
  • tbl\u post(iUserID、iPostID)
  • tbl\u积分(post\u id,积分)

但是,根据数据的大小,8-9秒可能是合理的。

您的查询是合理的,只是缺少明确的
join
语法

检查以确保您具有以下索引:

  • tbl\u friend(iUserId)
  • bar\u followers(iUserID)
  • tbl\u company\u follow(iUserID,iCompanyID)
  • tbl\u品牌(iCompanyID)
  • tbl\u post(iUserID、iPostID)
  • tbl\u积分(post\u id,积分)

但是,根据数据的大小,8-9秒可能是合理的。

如果不知道表的大小,很难判断10秒以下的查询时间是否合理。这可能是你能做的最好的了

也就是说,您可以重构此查询,以使用左连接操作代替依赖子查询。这将类似于这个大纲

SELECT tu.field, tu.field, ...
       a.count_f,
       b.bar_follows,
       ...
  FROM tbl_user tu
  LEFT JOIN (
              SELECT count(*) AS count_f, iUserID
                FROM tbl_friend
               GROUP BY iUserID
       ) a ON tu.iUserID = a.iUserId
  LEFT JOIN (
              SELECT count(*) AS bar_follows, iUserID
               FROM bar_followers
              GROUP BY iUserId
       ) b ON tu.iUserID = b.iUserId
 ...
这里有两件相关的事情。首先,每个
COUNT()
项都是
COUNT(*)
。这样就可以在不查看每行内容的情况下满足查询

其次,列列表中的依赖子查询将替换为计算所需聚合数据的子查询。这可能会有所帮助,因为查询计划器可以只执行一次每个子查询


Gordon关于索引的看法是对的。

如果不知道表的大小,很难判断10秒以下的查询时间是否合理。这可能是你能做的最好的了

也就是说,您可以重构此查询,以使用左连接操作代替依赖子查询。这将类似于这个大纲

SELECT tu.field, tu.field, ...
       a.count_f,
       b.bar_follows,
       ...
  FROM tbl_user tu
  LEFT JOIN (
              SELECT count(*) AS count_f, iUserID
                FROM tbl_friend
               GROUP BY iUserID
       ) a ON tu.iUserID = a.iUserId
  LEFT JOIN (
              SELECT count(*) AS bar_follows, iUserID
               FROM bar_followers
              GROUP BY iUserId
       ) b ON tu.iUserID = b.iUserId
 ...
这里有两件相关的事情。首先,每个
COUNT()
项都是
COUNT(*)
。这样就可以在不查看每行内容的情况下满足查询

其次,列列表中的依赖子查询将替换为计算所需聚合数据的子查询。这可能会有所帮助,因为查询计划器可以只执行一次每个子查询


Gordon关于索引的看法是正确的。

是你的朋友:)但是在这个大型查询中我如何管理它呢?但是它需要
8.3595秒
是你的朋友:)但是在这个大型查询中我如何管理它呢?但是它需要
8.3595秒
只有750条记录,而且需要这么多时间time@bluto . . . 改善了99.7%。不错;)对这对现在来说很好。。我将尝试使用
join
来实现这一点,因为只有750条记录,而且占用了这么多时间time@bluto . . . 改善了99.7%。不错;)对这对现在来说很好。。我将尝试使用
join