我有查询数据来自多个表。
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 seconds
如何最大限度地缩短时间?
答案 0 :(得分:3)
您的查询是合理的,除了缺少明确的join
语法。
检查以确保您拥有以下索引:
tbl_friend(iUserId)
bar_followers(iUserID)
tbl_company_follow(iUserID, iCompanyID)
tbl_brand(iCompanyID)
tbl_post(iUserID, iPostID)
tbl_points(post_id, points)
但是,根据数据的大小,8-9秒可能是合理的。
答案 1 :(得分:1)
如果不知道您的桌子大小,很难判断十分之一秒的查询时间是否合理。它可能接近你能做到的最好。
话虽这么说,您可以重构此查询以使用LEFT JOIN操作代替您的从属子查询。这将是这样的大纲。
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(*)
。这允许在不查看每行的内容的情况下满足查询。
其次,列列表中的从属子查询将替换为子查询,从而计算出所需的聚合数据。这可能会有所帮助,因为查询规划器只能执行一次每个子查询。
戈登关于指数的权利。