2012-01-03 55 views
2

我希望對以下連接有所幫助。 我有一個表(約2000萬行),其中包括:本身的表格連接 - 性能

MemberId(主鍵)| Id(主鍵)| TransactionDate |餘額

我想在一個查詢中獲得所有客戶的最新餘額。 我知道我可以做這樣的事情(我從我的記憶中寫下來)。但這種方式非常緩慢。

SELECT * 
FROM money 
WHERE money.Id = (SELECT MAX(Id) 
        FROM money AS m 
        WHERE m.MemberId = money.MemberId) 

是否還有其他(更快/更聰明)的選項?

+0

可以肯定,主鍵是合成的,第一列是MemberId? – Benoit 2012-01-03 14:12:45

+0

傘有一個很好的答案,但如果你不介意的話,我會非常有興趣瞭解MySQL如何處理'IN'運算符(替換第一個'=')。 – 2012-01-03 14:24:46

+0

@Benoit是的主鍵是複合的,第一列是MemberId(這是一個MyIsam表) – PKK 2012-01-03 14:28:24

回答

5

在我經歷的所有優化教程和截屏視頻中,聯接總是比子查詢更受歡迎。使用子查詢時,每次比較都會執行子查詢,而只有一次連接。

SELECT * 
FROM money m 
INNER JOIN (
    SELECT memberId, MAX(id) AS maxid 
    FROM money 
    GROUP BY memberId 
) mmax ON mmax.maxid = m.id AND mmax.memberId = m.memberId 
+0

真的很好的解決方案。它比我使用的查詢快得多 – PKK 2012-01-03 14:46:10

0

另一種選擇是查找在左NULL值加盟:

SELECT m1.* 
    FROM money m1 
    LEFT JOIN money m2 ON m2.memberId = m1.memberId AND m2.id > m1.id 
WHERE m2.memberId IS NULL 

但當然Umbrella's answer更好。

2

加入不是最好的方式去做這件事。考慮使用GROUP BY子句來篩選出最後的交易,每一個成員,就像這樣:

SELECT成員Id,MAX(ID)TransactionDate,餘額錢GROUP BY成員Id

UPDATE

作爲PKK指出的

,平衡將隨機選擇。看起來你畢竟需要進行某種連接。考慮這個選項:

SELECT MemberId, Id, TransactionDate, Balance FROM money WHERE Id IN (
    SELECT MAX(Id) FROM money GROUP BY MemberId 
) 
+0

當然...我怎麼可能不會想到這個... – Benoit 2012-01-03 14:13:14

+0

編輯得到Max Id而不是日期 – Umbrella 2012-01-03 14:14:14

+0

TransactionDate和Balance將隨機選擇。不是根據MAX(Id) – PKK 2012-01-03 14:18:36