MongoDB có luôn nhanh hơn MySQL?

Có thực sự MongoDB luôn nhanh hơn MySQL?

Như các bạn đã biết, chúng ta được biết đến MongoDB là một cơ sở dữ liệu có hiệu suất xử lý cao. Với những điểm đặc trưng như: phi cấu trúc, không ràng buộc, dễ dàng mở rộng ngang… vì vậy chúng ta luôn cho rằng với cơ chế hoạt động như vậy tốc độ xử lý của NoSQL sẽ luôn nhanh hơn các cơ sở dữ liệu quan hệ. Hôm nay chúng ta sẽ cùng nhau đi tìm hiểu sâu hơn và so sánh giữa MongoDB và MySQL liệu rằng MongoDB có luôn nhanh hơn MySQL hay không?

mongodb-co-luon-nhanh-hon-mysql

MongoDB có luôn nhanh hơn MySQL?

Để trả lời cho câu hỏi trên, chúng ta sẽ cùng nhau tìm hiểu sâu hơn về cơ chế hoạt động để có được câu trả lời thuyết phục nhất.

Quá trình xử lý truy vấn của MySQL như thế nào?

Cơ chế vận hành của MySQL được xây dựng dựa trên ý tưởng xử lý đa luồng multithreads để tăng hiệu suất xử lý của ứng dụng. Khi có nhiều truy vấn vào hệ thống, các thread (luồng), sẽ cùng nhau xử lý song song để cho ra kết quả sớm nhất. Ở một số trường hợp khi hệ thống high load (chịu tải ở mức độ cao), khi MySQL không xử lý kịp thời tất cả trong số chúng, thì một queue (hàng đợi) sẽ sắp xếp tuần tự các yêu cầu truy vấn, các thread sẽ lần lượt lấy các yêu cầu cũ nhất theo tuần tự để xử lý song song cùng nhau cho đến hết. Trong trường hợp bạn sử dụng storage engine (Kiến trúc lưu trữ) là InnoDB các write query. Khi có nhiều các truy vấn cập nhật dữ liệu đồng thời trên một bản ghi thì cơ chế Row Locking của MySQL sẽ phát huy tác dụng. Cơ chế này sẽ khóa bản ghi đang thực hiện lại, các truy vấn tác động tới bản ghi sẽ được đưa vào hàng đợi tới khi thực hiện hoàn thành thì mới tiếp tục xử lý từ hành động đầu tiên cho tới hết. Cùng lúc đó các truy vấn write query tác động tới các bản ghi khác vẫn được thực hiện bình thường thông qua các thread khác.

MongoDB xử lý truy vấn như thế nào?

Cơ chế vận hành xử lý của MongoDB hoàn toàn khác so với MySQL. Bài viết chỉ tập trung vào các điểm quan trọng, bỏ qua các điểm không quan trọng khác. Các write query của MongoDB không được xử lý song song cùng một lúc. Tại một thời điểm chỉ có một truy vấn được xử lý. Tất cả các truy vấn của MongoDB đều được đưa vào một hàng đợi để xử lý tuần tự, như các bạn đã biết đối với hàng đợi thì vào trước ra trước. Kỹ thuật mà MongoDB sử dụng có tên là: instance-wide-locking tức là cả một hệ thống MongoDB chỉ xử lý một truy vấn tại một thời điểm. Hình dung qua về cơ chế vận hành như vậy thì rõ ràng là MySQL xử lý tốt hơn rất rất nhiều MongoDB rồi phải không nào? Tuy nhiên với kiến trúc dữ liệu như đã nói ở đầu bài viết thì điều này chưa hoàn toàn đã có thể khẳng định được rằng MongoDB luôn nhanh hơn MySQL được.

Làm sao để so sánh được MongoDB và MySQL?

Nếu chúng ta xét về khía cạnh hiệu suất của một truy vấn đơn giản thông qua trường _id của MongoDB thì rõ ràng là MongoDB sẽ luôn nhanh hơn MySQL trong mọi trường hợp. Mình đã từng vận hành một số dự án có sử dụng MySQL và MongoDB thì chỉ có thể thấy được sự khác biệt khi ứng dụng của chúng ta chịu tải một lượng yêu cầu cực lớn, những câu truy vấn có độ phức tạp cao. Ở MySQL thì chúng ta có khái niệm Indexes để lập chỉ mục tăng tốc độ vận hành. Ở MongoDB cũng có indexes, nhưng dường như các DBA ít quan tâm về điều này. Điều mình muốn nói ở đây là trong mọi CSDL thì Indexes luôn có vai trò quan trọng trong tối ưu hiệu suất hoạt động.

Tầm quan trọng của Indexes (chỉ mục) trong MongoDB

Như đã nói ở trên MongoDB sử dụng kỹ thuật instance-wide-locking cho các write query. Để dễ hiểu hơn mình sẽ ví dụ cho các bạn trong trường hợp CSDL của chúng ta có vài triệu bản ghi và chúng ta cần thực hiện cập nhật 100 bản ghi trong số đó, trường hợp chúng ta đều không sử dụng Index thì điều gì sẽ xảy ra?

  • MySQL bắt đầu xử lý với một thread, thực hiện (full table scan) thao tác quét bảng vì ở đây chúng ta không sử dụng index. Hệ thống sẽ phải quét qua từng bản ghi và thực hiện cho tới khi hoàn tất. Mình đã kiểm thử trên CSDL của mình và thời gian mất vào 30 phút, bởi vì cấu hình của máy mình hơi thấp. Trong lúc này các hành động ghi khác của mình trên client khác vẫn được xử lý bình thường.
  • MongoDB cũng bắt đầu xử lý thao tác quét bảng nhưng cơ chế instance-wide-locking của MongoDB sẽ được kích hoạt lên để ngăn chặn và đưa tất cả các hành động cập nhật khác vào hàng đợi để xử lý sau. Thời gian của MongoDB xử lý nhanh hơn rất nhiều, mất chừng 10 phút.

Như các bạn có thể thấy thời gian của MongoDB cho kết quả ấn tượng hơn phải không nào? Có lẽ nó nhanh hơn bởi vì trong cùng một thời gian đó MongoDB được chuyên tâm làm việc và không bị ai làm phiền. Còn MySQL thì phải chia ra cho nhiều người cùng thao tác vào thì rõ ràng là nhanh hơn phải không nào?

Điều này sẽ cực kỳ nghiêm trọng khi ở các web service như apache, PHP thường quy định thời gian xử lý tối đa của script là 30 giây. Nếu trong lúc Client khác đang chờ được MongoDB xử lý truy vấn của mình quá thời gian cho phép thì lập tức script sẽ bị dừng lại. Đây quả là một điều tệ hại phải không nào?

Nhưng các bạn cũng cần lưu ý trường hợp trên mình không sử dụng index để CSDL phải thực hiện full table scan để thấy được rõ ràng về thời gian. Còn trong thực tế chúng ta luôn cần phải sử dụng index cho CSDL của mình để tăng thời gian đáp ứng và xử lý.

Kết luận

Như các bạn thấy đó, với các truy vấn đơn giản, không có độ phức tạp lớn thì MongoDB luôn nhanh hơn MySQL, nhưng không có nghĩa rằng nó sẽ xử lý nhanh hơn trong mọi trường hợp phải không? Ngay cả một cơ sở dữ liệu phi cấu trúc như MongoDB chúng ta cũng cần quan tâm tới indexes để tăng thời gian tìm kiếm dù có xử lý nhanh hơn đi nữa. Hiện nay MongoDB đã bắt đầu bổ sung cơ chế database-wide-locking cho core xử lý của mình, điều này có lẽ rằng các hành động sẽ không bị khóa ở mức toàn hệ thống MongoDB nữa, mà chỉ ở mức các database. Điều này cũng đã giúp cải thiện được khá nhiều của các bài toán thực tế của chúng ta rồi. Hi vọng với bài viết này, các bạn sẽ có thêm kiến thức để góp phần đưa ra những quyết định đúng đắn cho công việc của mình sau này.