Dear mọi người, mình đang có 1 vấn đề về mảng control version như thế này, nhờ mọi người giúp đỡ.
Database của mình được thiết kế để theo dõi và quản lý version (history) của các item.
Để mô tả hết thì khá phức tạp nên xin phép mô tả hình tượng hóa và chỉ ra vấn đề như sau:
I. Giả sử có 1 bảng A có cấu trúc và dữ liệu như bên dưới:
Id Name Insert_Date Other_Columns
--------------------------------------------------
1 A 20160101 A_data_1
2 A 20160202 A_data_2
3 A 20160401 A_data_3
4 B 20160111 B_data_1
5 B 20160121 B_data_2
6 C 20160301 C_data_1
Hiện tại có 2 index của bảng:
index_1 : (Name)
index_2 : (Name, Insert_Date)
Khối lượng data trong bảng A khá lớn (khoảng 16 triệu bản ghi)
II. Bài toán:
Nhập vào 1 ngày, ví dụ 20160325. Search ra (Name, Insert_Date, Other_Columns) của các bản ghi có insearch date nhỏ hơn và gần ngày nhập vào nhất. Và ứng với mỗi 1 Name thì chỉ lấy 1 record thôi.
Ví dụ như data ở phía trên thì sẽ return ra result sau:
Name Insert_Date Other_Columns
-------------------------------------------
A 20160202 A_data_2
B 20160121 B_data_2
C 20160301 C_data_1
III. Solution hiện tại:
Hiện tại em đang sử dụng lệnh sau:
SELECT a1.*
FROM A a1 LEFT JOIN A a2
ON (a1.name = a2.name AND a1.Insert_Date < a2.Insert_Date AND a2.Insert_Date < @inputdate)
WHERE a2.Insert_Date IS NULL
And a1.Insert_Date < @inputdate;
Note: @inputdate là ngày user nhập vào, ví dụ như 20160325.
Đây là solution được dựa trên topic sau: http://stackoverflow.com/questions/1313120/retrieving-the-last-record-in-each-group.
IV. Issue:
Trong trường hợp có ít nhất 1 bản ghi phù hợp thì lệnh trên tỏ ra khá nhanh.
Tuy nhiên trong trường hơp không có bản ghi nào < @inputdate thì rất chậm.
Nguyên nhân có thể là do mysql đã phải full scan table.
V. Kết: mình không có nhiều kinh nghiệm về mysql, tuy nhiên mình nghĩ đây là vấn đề khá thường xuyên sảy ra trong các hệ thống lớn. vì thế nếu mọi người có time xin hãy chia sẻ kinh nghiệm.
Đã được chỉnh sửa lần cuối bởi kiemkhach : 26-03-2016 lúc 10:24 AM.
cho bạn
lưu ý là kết quả trên ví dụ của bạn có thể sai nếu format date là yyyy/mm/ddCode:select a.Name,a.Insert_Date,a.Other_Columns from a where (a.Name,a.Insert_Date) in ( select a.Name,max(a.Insert_Date) from a group by a.Name )