MySQL查询优化。许多SELECT + INNER JOIN

时间:2013-12-20 23:50:14

标签: mysql select

我有下一个表结构: 游戏 - 包含基本游戏信息(体育赛事), 投注 - 投注变化(团队获胜,团队b获胜等), 投票 - 用户选择投注变化。

下一个查询显示所有未开始游戏的所有最后投注变化的列表。 如果当前用户投票,列表中的某些投注也包含一些信息。

用于检测的插入选择下一个: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?

1 个答案:

答案 0 :(得分:7)

您的left join没用,因为您在第二个表中使用了一个值。因此,为了清楚起见,我会将其更改为inner join

此外,YNPT的子查询没有聚合,因此它们似乎可以返回多行。我假设应该有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)