Cách xử lý thông minh nhât cho truy vấn
Chào mọi người, mình có 1 bảng trong database Cứ sau 1 ngày mình có 1 con cronjob chạy lúc 3h sáng. chuyển điểm từ cột A sang cột B. Hiện tại code đang là như này:
$a = KhachHang::where('ID',$ID)->first();
$sodiem = $a->cot_a;
$a->decrement('cot_a',$sodiem); // - trừ
$a->increment('cot_b',$sodiem); // + cộng
Vấn đề hoàn toàn bình thường, nhưng dữ liệu của mình tầm khoảng 1 triệu bản ghi nên khi thực hiện khá lâu. Vậy cho mình hỏi có cách nào để xử lý vấn đề này tốt nhất? Thanks
6 CÂU TRẢ LỜI
Cảm ơn ý kiến mọi người, sau một hồi thảm khảo mình nghĩ chỉ có cách này giải quyết tạm ổn vấn đề. Thank you so much.
dùng paginate của laravel để phân trang các id của khách hàng: DB::table('KhachHang')->paginate(200) // [ 1, 2,...., 200]
sau đó duyệt mảng vừa lấy ra được chay query thuần: update khach_hang set cot_at = cot_a + so_diem, set cot_b = cot_b - so_diem where ID in (1,2,3,4,5....,200)
Tại sao phải chạy querry thuần ?
@tinhtn89 không thì bạn viết code bằng laravel cũng được, nhưng khi thực thi thì câu query phải có dạng như vậy.
Không hiểu câu hỏi lắm là update cho 1 record hay nhiều record
Chậm do đâu, do chạy từng query với mỗi id trong loop hay do chưa có index ?
Nếu là truy vấn trong loop thì chuyển thành 1 câu bulk update thôi.
Chậm là do nó phải xử lí nhiều record ( tầm gần 1 triệu)
@tinhtn89 vậy là update từng record trong tập 1 triệu record đó ? Thế thì lưu id thành array rồi khi đủ tầm 10k-100k id thì chạy update where in.
ừ, cách đó thì m biết, đang tham mưu xem có cách gì ngon hơn không ấy.
nếu cấu trúc dạng update như kia, bạn có thể thử cách sau:
update bảng KhachHang và set cot_a = 0 (decrement đi $sodiem thì cũng là trừ đi chính cái cot_a đó thì luôn = 0) cot_b = cot_b + cot_a Where: cái này thì như câu lệnh trên đã có sẵn id, nếu ko muốn chạy dạng loop thì where in hay gì đó mà bạn có.
Performance thì mình cug ko chắc là nhanh hay chậm, chỉ là 1 cách có thể tham khảo thêm,
Update muốn nhanh thì chắc có select bản ghi ra insert vào bảng mới, dùng join để update data giữa bảng mới và bảng cũ.
Bạn thử chạy 2 câu query kiểu này xem đc không
UPDATE KhachHang SET cot_b = cot_b + cot_a WHERE ID IN (id1,id2,...)
UPDATE KhachHang SET cot_a = 0 WHERE ID IN (id1,id2,...)