Cần tư vấn giải pháp MySQL lớn lên đến 10 triệu rows
Chào các bác,
Mình cần tư vấn giải pháp VPS, Server, MySQL, khi data của mình khá lớn, lên đến 10 triệu rows/ bảng ghi table.
Mình đang dùng VPS RAM 8GB, 4CPU tại DO, online cùng lúc tầm 1k. Em theo dõi RAM sử dụng tầm dưới 1Gb, CPU 20%. Nhưng website load khá chậm, em nghĩ do requetes sql khá lớn.
Xin hậu tạ bác nào giúp được.
Xin cảm ơn ạ.
7 CÂU TRẢ LỜI
Trước hết, bạn cần phải xác định được xem câu querry nào thực sự đã làm chậm quá trình load website của bạn. Bạn có thể thực hiện việc đó bằng cách bật chức năng log slow queries của Mysql lên:
# Enable slow query log
SET GLOBAL slow_query_log = 'ON';
# Chỉnh lại thời gian của query được nhận định là long query, mặc định là 10 giây
SET GLOBAL long_query_time = 1;
# Check xem slow query logs sẽ được lưu ở đâu
SELECT @@GLOBAL.slow_query_log_file;
# Bạn có thể thay đổi file mặc định này bằng cách
SET GLOBAL slow_query_log_file = '/path/to/filename';
Ngoài ra, bạn cũng nên bật cả log query để check xem có bao nhiêu query đã được thực hiện nữa
SET GLOBAL general_log = 'ON';
# Check xem query logs sẽ được lưu ở đâu
SELECT @@GLOBAL.general_log_file;
Sau đó hãy thử reload lại trang web để tìm ra nguyên nhân cho việc làm giảm performance service của mình nhé.
Một số nguyên nhân cơ bản có thể kể ra như:
- Gặp phải vấn đề về
n+1
query, dẫn đến lượng truy vấn database quá lớn - Sử dụng nhiều lệnh join phức tạp, cột dữ liệu cần truy vấn chưa được đánh index ...
Sử dụng nhiều lệnh join cũng làm chậm mysql sao bác , em thấy câu lệnh join nó cải thiện tốc độ truy vấn nhiều chứ .
@kanran111 Mình không nói là sử dụng lệnh join
làm chậm mysql, mà nói sử dụng nhiều lệnh join phức tạp qua quá nhiều bảng với các cột chưa được đánh index có thể là nguyên nhân làm chậm
Bạn có ở HCM ko, có thể gặp trực tiếp mình để tối ưu giúp mình database này không? Mình trả phí xứng đáng. Cảm ơn bạn.
@daithinh Rất tiếc mình lại không ở TPHCM bạn ạ. Nếu bạn có thắc mắc hay gặp vấn đề gì thì có thể hỏi trên Viblo này để mọi người cùng vào giúp đỡ nhé :slight_smile:
Tại vì mình ko chuyên bên kỹ thuật, nên có biết cách sửa cũng sửa ko sửa được nữa. Nếu được bạn teamview sửa giúp mình được không? Mình sẽ hậu tạ. Skype: quocdai1230 Cảm ơn bạn trước.
@kanran111 bro đã lên tiếng rồi còn gì bàn.
Câu hỏi của bạn khá chung chung. Nói về MySQL thì 10 triệu dòng không phải là con số nhỏ, nhưng cũng không phải là con số lớn. Trên thế giới đã có rất nhiều Web Site đã Scale MySQL với lượng Data lớn hơn thế này nhiều. Có thể đi theo 1 vài bước sau:
- Optimize Query: Bạn có thể xem cách đọc các Query bị chậm như cách của anh Thắng bên trên, hoặc lấy trực tiếp các Query mà bạn nghi là chậm sau đó chạy trên MySQL Command sẽ thấy thời gian chạy của Query đó. Bạn có thể xem thêm khoá học này để hiểu thêm về cách Optimize Query: https://goo.gl/md5QdB
- Replication. Sử dụng cơ chế Replication của MySQL, tạo 1 bản Master chuyên ghi DB và 1 bản chuyên đọc. Giải pháp này nếu như MySQL DB của bạn thường xuyên được ghi vào.
- Caching. Một giải pháp Caching hay sử dụng hiện nay là Redis. Tốc độ của nó cực cao, nên bạn cứ yên tâm mà sử dụng. Bên Stackoverflow họ dùng SQL Server và Redis để Caching, tốc độ vào trang của họ thì bạn cũng biết rồi đó. Còn về cơ chế Cache thì cũng đơn giản, đầu tiên là kiểm tra ID của bản ghi đó có tồn tại trong Cache không, nếu có thì lấy từ Cache, không thì Query từ DB ra, sau đó cũng Cache bài đó vào Redis. Nếu trang bạn là tin tức là có thể chạy Crontab mỗi ngày lấy ra 100 bài nhiều người đọc nhất, xong đưa vào Cache. Nhìn chung giải quyết vấn đề cho các trang tin tức dễ hơn là các trang thương mại điện tử vì trang tin thì đọc ra là chủ yếu. Về DO thì các vấn đề như Network hay CDN chắc không phải là vấn đề.
Không có một thông tin gì chi tiết nên mình cũng không thể comment gì về cách cải thiện cả. Tuy nhiên với những bảng data với số lượng lớn bản ghi bạn nên cân nhắc chuyển sang dùng NoSQL, độ linh hoạt của query sẽ bị hạn chế nhưng tốc độ đọc ghi thì vô đối Về NoSQL thì nếu có tiền thì xài hàng của AWS, còn không thì có thể dùng Cassandra hoặc MongoDB chẳng hạn.
Ngoài ra cải thiện tốc độ của MySQL thì cũng chỉ có thể có một vài cách là tối ưu lại các câu SQL, thực hiện caching cho các query được gọi đi gọi lại nhiều lần thôi Hi vọng giúp ích được cho bạn.
Nếu viết mới thì điều đó đơn giản. Nhưng nếu hệ thống đang chạy rồi mà convert dữ liệu đó sang NoSQL hoặc cái khác là cả một vấn đề đó bạn.
@gaubdeodeptrai Migrate data thì có bao giờ đơn giản đâu bạn Quan trọng là để giải quyết vấn đề thì đó là một cách làm. Bên dưới mình cũng nói là nếu vẫn giữ MySQL thì phải làm gì rồi mà
Bạn có thể chia sẻ thiết kế các bảng liên quan cũng như query log của bạn ra đây được không?
Cấu trúc dữ liệu thế nào, theo mình chuyến sang nosql để tăng tốc độ là ngon nhất
Cá nhân mình thấy 10 triệu records thì bảng cũng chưa phải là quá lớn, chắc có thể fit hoàn toàn trên RAM. CPU cao thì nên check lại xem query nào mất nhiều thời gian nhất, index đánh đã đủ chưa.
Bạn nên thử dùng clickhouse. Bảng trên 10 tỉ dòng vẫn query ngon. Performance gấp 1000 đến 10000 lần Mysql. Mongo không cấu trúc nên không linh động câu query.
mình góp ý là lấy những gì cần lấy, tối ưu queries và sử dụng thêm elasticsearch, nếu data quá lớn thì có thể dùng sang db khác như cassandra or dynamodb nếu có điều kiện, ngoài ra dùng dataloader để batching và caching dữ liệu