2012-04-12 42 views
2

我有表players,players_to_teamsaccountsplayers_to_teams的FK爲playersaccountsplayers有一個FirstNameaccounts有一個Name。索引FirstNameName爲什麼這兩個(類似的?)MySQL查詢在執行時間上差異很大?

運行

SELECT players_to_teams.id 
FROM players_to_teams 
INNER JOIN players 
ON players.id = players_to_teams.player_id 
ORDER BY players.FirstName 

執行0.004秒。

SELECT players_to_teams.id 
FROM players_to_teams 
INNER JOIN accounts 
ON accounts.id = players_to_teams.account_id 
ORDER BY accounts.Name 

執行超過7秒。

有30,000個帳戶記錄和250k玩家記錄。

EXPLAIN S能在這裏找到:https://gist.github.com/2368906

不宜這些查詢在相似的時間間隔執行?

+0

你有多少個賬戶? – Rufinus 2012-04-12 16:56:32

+0

它與連接表具有的列或記錄的數量(我不記得)有關。我記得前一段時間在數據庫類中看到了這個概念。讓我更新我的想法。 – 2012-04-12 16:57:57

+0

也許account_id在palyers團隊沒有索引? – kappa 2012-04-12 17:03:08

回答

1

你較慢的查詢需要一個臨時表來排序結果集,而另一個可以使用FirstName上的索引,避免排序在一起。 (額外:使用索引;使用臨時;使用filesort)

你可以嘗試強制帳戶的索引,看看你是否可以勝過優化?

SELECT players_to_teams.id 
FROM players_to_teams 
INNER JOIN accounts FORCE INDEX(Name) 
ON accounts.id = players_to_teams.account_id 
ORDER BY accounts.Name 

另一種替代方法是用直接連接重寫查詢,並首先列出帳戶表。

我沒有任何好的答案,爲什麼它當前選擇players_to_teams首先帳戶有少行少。

+0

什麼是直接連接? – 2012-04-12 17:58:27

+0

'FORCE INDEX'工作,btw – 2012-04-12 18:07:42

+0

直接連接將強制MySQL按照您指定的順序使用這些表。 [http://dev.mysql.com/doc/refman/5.1/en/join.html](http://dev.mysql.com/doc/refman/5.1/en/join.html) – ESG 2012-04-12 18:10:35

1

另一個選項可能有助於......我記得在某處閱讀......如果您的帳戶ID和名稱都是索引(id,name),那麼引擎不必返回到原始數據記錄以提取名稱值,並可以直接從索引中提取它...從而節省了從匹配的完整記錄讀取時間。

+0

'accounts'有'id_name'複合索引。那是你在想什麼? – 2012-04-12 17:16:24

+0

@TylerDeWitt,yup ... – DRapp 2012-04-12 17:50:28

相關問題