這並不重要,你只能得到10行。在對數據進行排序之前,MySQL必須總結每個用戶的要點(「使用filesort」操作)。LIMIT最後應用。
覆蓋指數ON points(user_id,point)
將是最佳性能的最佳選擇。 (我真的只是猜測,沒有任何EXPLAIN
輸出或表定義。)
列users
可能是主鍵或至少一個唯一的索引。所以,很可能你已經有一個索引與id
作爲前導列,或者如果它是InnoDB的主鍵簇索引)
我會忍不住來測試這樣的查詢:
SELECT u.*
, s.total_points
FROM (SELECT p.user_id
, SUM(p.point) AS total_points
FROM points p
WHERE p.user_id > 0
GROUP BY p.user_id
ORDER BY total_points DESC
LIMIT 10
) s
JOIN user u
ON u.id = s.user_id
ORDER BY s.total_points DESC
那請問有創建派生表的開銷,但有一個合適的索引點,包含user_id的前導列,並且包含point列,所以MySQL很可能通過使用索引來優化組,並避免使用「Using filesort」操作(對於GROUP BY)。
在結果集上可能會有一個「使用filesort」操作,以獲得按total_points排序的行。然後從中獲得前10行。
使用這10行,我們可以加入到用戶表中以獲取相應的行。
但是..這個結果有一個細微的差別,如果user_id
的任何值在前10位不在用戶表中,那麼這個查詢將返回少於10行。 (我希望有一個外鍵定義,所以這不會發生,但我真的只是猜測沒有表定義。)
EXPLAIN
將顯示MySQL正在使用的訪問計劃。
對於這麼小的表索引您參加的列上應該足以使這個查詢瞬間。 – piotrm