我有一個數據庫用戶和facebook_accounts,屬於用戶。用戶按照與其他用戶相關的點數「排列」:這是通過嵌入式SELECT語句完成的,該語句用比用戶多得多的點數來計算所有用戶。MySQL排名查詢和左加入
該數據庫擁有〜10k個用戶。下面的SQL查詢需要的MySQL〜0.16s滿足:
SELECT
*, (SELECT (COUNT(*) + 1)
FROM users AS UserHigher
WHERE UserHigher.points > User.points
) AS rank
FROM
users AS User
ORDER BY
User.points DESC, User.created ASC
LIMIT 0, 30
然而,加入LEFT JOIN也檢索用戶的facebook_account掛起MySQL的:
SELECT
*, (SELECT (COUNT(*) + 1)
FROM users AS UserHigher
WHERE UserHigher.points > User.points
) AS rank
FROM
users AS User
LEFT JOIN
facebook_accounts AS FacebookAccount
ON (FacebookAccount.user_id = User.id)
ORDER BY
User.points DESC, User.created ASC
LIMIT 0, 30
據我所知,COUNT()選擇排序用戶的方法效率不高,但這是我遇到的最可靠的方法。我不明白的是,爲什麼一個簡單的LEFT JOIN會破壞一個合理的查詢,當它看起來與排名SELECT語句完全分離時。
有什麼建議嗎?
你對這些列的索引? 'EXPLAIN'告訴你什麼? – 2013-02-23 00:24:41
不要每次都讀取所有數據。 – symcbean 2013-02-23 00:44:04
所有表都有唯一的每行數字索引,而FacebookAccounts中的user_id是foriegn鍵列。 這是兩個查詢的EXPLAIN的屏幕截圖。 https://dl.dropbox.com/u/225179/temp/sql-queries.png 看起來JOIN強制PRIMARY用戶表使用「臨時」,所以也許從限制0,30的優化在那裏丟失 – 2013-02-23 00:46:06