專案經理回報網頁載入緩慢,開發已加入 Memcached 20 分鐘快取仍無改善。經 SQL 分析,發現單一查詢耗時 5 秒以上,為效能瓶頸。
SELECT *
FROM (
SELECT u.NAME AS UniversityName,
u.id AS UniversityId,
COUNT(a.SIGNUPNUMBER) AS playercnt
FROM T_B_UNIVERSITY u
LEFT JOIN T_D_EDUCATION e ON e.UNIVERSITY_ID = u.id
LEFT JOIN T_D_VIDEO_PLAYER a
ON a.USER_ID = e.user_id
AND e.ISDEFAULT = 1
AND e.ISVALID = 1
AND a.AUDITSTATUS = 1
AND a.ISVALID = 1
LEFT JOIN T_D_USER c
ON a.USER_ID = c.id
AND c.ISVALID = 1
WHERE u.REGION_CODE LIKE '43%'
GROUP BY u.NAME, u.id
) t
ORDER BY playercnt DESC;
E.ISVALID=1 AND E.ISDEFAULT=1 在 FILTER (Id 10) 執行,而非 JOIN 時過濾T_D_VIDEO_PLAYER 全表掃描 (Id 11)將右表的過濾條件從 WHERE 移至對應的 ON 子句:
SELECT *
FROM (
SELECT u.NAME AS UniversityName,
u.id AS UniversityId,
COUNT(a.SIGNUPNUMBER) AS playercnt
FROM T_B_UNIVERSITY u
LEFT JOIN T_D_EDUCATION e
ON e.UNIVERSITY_ID = u.id
AND e.ISDEFAULT = 1
AND e.ISVALID = 1
LEFT JOIN T_D_VIDEO_PLAYER a
ON a.USER_ID = e.user_id
AND a.AUDITSTATUS = 1
AND a.ISVALID = 1
LEFT JOIN T_D_USER c
ON a.USER_ID = c.id
AND c.ISVALID = 1
WHERE u.REGION_CODE LIKE '43%'
GROUP BY u.NAME, u.id
) t
ORDER BY playercnt DESC;
T_D_VIDEO_PLAYER 讀取行數從全表降至 78 行LEFT JOIN 右表條件放在 WHERE 會隱性轉為 INNER JOIN,導致:
放在 ON 子句則保持外部連接語義,優化器可提前過濾右表,大幅縮小中間結果。
| 指標 | 修正前 | 修正後 |
|---|---|---|
| 執行時間 | > 5 秒 | 0.1 秒 |
| Estimated Cost | 170 | 25 |
| 中間結果行數 | 672 | 301 |
SET STATISTICS IO, TIME ON 驗證執行計畫