我有下一个表结构:游戏-包含基本游戏信息(体育赛事),下注-投注变化(A队获胜,B队获胜等),选票-用户选择投注变化。
下一个查询显示所有未开始游戏的最后赌注变化列表。如果当前用户投票赞成的话,列表中的一些赌注也包含一些信息。
Inserted用于下一步检测:1-用户是否已经投票支持此打赌?,2-获取用户的选择(是\否),3-获得用户的投票量。
SELECT bets.*, games.Time, games.TA, games.TB,
(SELECT COUNT(*) FROM votes WHERE BID=bets.BID AND UID=$UserID) AS Vt,
(SELECT YN FROM votes WHERE BID=bets.BID AND UID=$UserID) AS yn,
(SELECT Pt FROM votes WHERE BID=bets.BID AND UID=$UserID) AS Pt
FROM bets
LEFT JOIN games ON games.GID = bets.GID
WHERE games.Yes=0 AND bets.Dl=0
ORDER BY bets.Time DESC我如何优化它?如何在一个查询中获取votes.YN和votes.Pt?
发布于 2013-12-20 23:56:18
您的left join是无用的,因为您使用的是第二个表中的值。因此,为了清晰起见,我将把它更改为inner join。
此外,YN和PT的子查询没有聚合,因此它们似乎可以返回多个行。我想应该有一个sum()。
然后,我将三个相关的子查询移到from子句中。这需要bid进行聚合。
SELECT bets.*, games.Time, games.TA, games.TB,
coalesce(v.vt, 0) as vt, coalesce(v.yn, 0) as yn, coalesce(v.pt, 0) as pt
FROM bets inner join
games
ON games.GID = bets.GID left join
(select bid, count(*) as vt, sum(yn) as yn, sum(pt) as pt
from votes v
where UID=$UserID
group by bid
) v
on v.bid = bets.bid
WHERE games.Yes=0 AND bets.Dl=0
ORDER BY bets.Time DESC;编辑:
让我指出,这可能提供或不可能提供更好的性能(取决于where子句的选择性)。有了防止所有行远离left outer join的bets,它可能会更好。
添加以下索引应修复查询的原始版本:votes(bid, uid)。
https://stackoverflow.com/questions/20713737
复制相似问题