customer-report-jp.html
Về phản hồi từ khách hàng 「CMS 側の反応スピードが遅い」 (tốc độ phản hồi phía CMS rất chậm), đội đã phân tích video khách gửi kèm với source code liên quan và xác định được nguyên nhân gốc cùng lộ trình khắc phục.
Đội đã phân tích từng frame của video 60 giây khách gửi → xác nhận bảng creator không load xong cho đến hết video.
/revenue-partnership-creator
Phân tích SQL của API GET /cms/revenue/partnership cho thấy 4 vấn đề thiết kế cộng dồn
tạo nên độ trễ này.
Một query lấy dữ liệu, một query đếm tổng số trang (COUNT) — cả 2 chạy cùng 1 SQL với 10 LEFT JOIN giống y hệt. DB phải làm cùng phép tính nặng 2 lần liên tiếp cho mỗi request.
backend/src/app/admin/revenue/revenue.service.ts : 5397–5432
Một sub-query gồm UNION 5–6 phần (video_view + video_comment + 3 sub-query trên bảng lịch sử giao dịch) được dán nguyên xi vào 3 chỗ khác nhau trong query chính. MySQL không cache derived table → phải thực thi UNION này lặp lại 3 lần.
revenue.service.ts : 5120, 5134, 5152
Doanh thu video, coin bình luận, reaction, share, follower, subscription, single-item … 10 loại aggregate được LEFT JOIN trong 1 query. MySQL phải dựng đầy đủ 10 derived table xong rồi mới join với memberId. Không có LIMIT trên sub-query → không thể short-circuit.
revenue.service.ts : 5345–5393
Admin thường mở lại cùng filter (cùng khoảng tháng, cùng plan type) nhiều lần trong ngày, nhưng mỗi lần là chạy lại y nguyên SQL khổng lồ từ đầu. Không Redis cache, không HTTP cache — F5 cũng không nhanh hơn.
Ước tính trên data size hiện tại của STG (video_view ~5M dòng, transaction history ~3M dòng)
Cách tiếp cận theo bậc thang: ngắn hạn ăn ngay lợi lớn → trung hạn fix triệt để → dài hạn xây nền cho các trang aggregate khác.
Đổi câu COUNT để chỉ chạy trên driving table (memberVideos) thay vì re-join toàn bộ 10 bảng. Do toàn bộ là LEFT JOIN nên số dòng cuối không thay đổi → COUNT trên driving table cho ra cùng kết quả. Giải quyết ngay vấn đề "chạy 2 lần".
Refactor: dùng CREATE TEMPORARY TABLE cho khối UNION 5–6 phần,
rồi 3 chỗ trong main query chỉ reference temp table. MySQL chỉ phải tính UNION 1 lần.
Giải quyết vấn đề "lặp 3 lần".
Cache key = hash(date range + filters), TTL 5–10 phút. Hạ tầng đã có Redis sẵn, chi phí thêm gần như 0. Lần thứ 2 admin mở cùng filter sẽ trả về tức thì.
Tạo bảng denormalized partnership_revenue_daily,
worker cron-job-service đã có sẵn sẽ refresh mỗi 15–30 phút.
Lúc đó query chính chỉ còn SUM GROUP BY trên bảng nhỏ.
Áp dụng được cho cả các trang aggregate khác trong tương lai.
Mức cải thiện cộng dồn qua từng bước fix
BA + dev review bản tiếng Việt này trước. Sau khi confirm content + đồng ý thứ tự ưu tiên
(Bước 1 đi trước, hay đẩy Bước 3 Redis lên trước để hiệu quả nhanh cho lần load thứ 2?),
team sẽ translate sang JP gửi khách hàng.
Khuyến nghị: commit Bước 1 ngay (effort 1 ngày, giảm 50%) để có evidence trước khi reply KH.
analysis/perf-root-cause.mdanalysis/customer-report-jp.htmlattachments/gyazo_…mp4