2013-12-20 169 views
0

我有下一個表格結構: 遊戲 - 包含基本遊戲信息(體育賽事), 下注 - 下注變化(球隊a贏,球隊b贏等), 投票 - 用戶選擇下注變化。MySQL查詢優化。許多SELECT + INNER JOIN

下一個查詢顯示所有未開始遊戲的所有最後下注變化的列表。 如果當前用戶投票支持,列表中的某些投注還包含一些信息。

用於下次檢測插入選擇:1 - 是用戶已經投給了這個賭?2 - 獲取用戶的choise(是\否),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?

+0

只有SQL是相關的,而不是[破壞]的調用。 – user2864740

+0

順便說一句,這是一個內部加入! – Strawberry

回答

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)

+0

這很好ñ快!你是我的靈感之一! –

+0

但是,在用戶的身份(我需要投注數據僅供投注者由當前用戶投票)的情況下,還可以告訴我您使用的SUMs是什麼? –

+0

@SirD。 。 。我已經加入了一個'coalesce()',當沒有投票時,它將'0'代替'NULL'。 –