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