面對 users (一) 對 login_log (多) 的關聯,需查詢每位用戶最新的一條日誌。傳統 INNER JOIN + 子查詢 寫法雖正確但效率一般。本文提出「先查主表,再以主鍵反查從表取最新」的應用層分頁思路,並對比原始 SQL 與優化理解。
SELECT u.first_name, u.email_address, u.tp_user_id, u.tp_username,
l.module_access, l.created_date
FROM users u
INNER JOIN auth_token_log l ON u.id = l.user_id
WHERE l.id IN (
SELECT MAX(id) FROM auth_token_log
WHERE user_id = u.id
);
外層先產生關聯結果集,再對每一行執行子查詢取該用戶最大 id,等價於「對每個用戶單獨查詢最新日誌」。
SELECT * FROM users WHERE ... LIMIT 20 取用戶列表。IN 條件一次查詢:SELECT * FROM auth_token_log WHERE user_id IN (...) ORDER BY user_id, id DESC。user_id 分組取第一條,即為各用戶最新日誌。此法將複雜 JOIN 轉為兩條簡單查詢,減少資料庫負載,適合高併發場景。