TL; DR:$inc
đảm bảo cập nhật tại chỗ, $set
không, nhưng trong những trường hợp rất cụ thể, nó cũng có thể được thực hiện tại chỗ.
Chi tiết
Có hai khía cạnh của vấn đề này:
-
nó đi qua dây như thế nào?
Thông tin được gửi dưới dạng một hoạt động, một
$set
vẫn là một$set
vì vậy nó là một vùng đồng bằng. Điều đó cũng đúng đối với oplog được sử dụng để sao chép. Theo cách này, sử dụng$set
hiệu quả hơn về băng thông. -
nó được cập nhật trên đĩa như thế nào?
MongoDB thực hiện cập nhật tại chỗ nếu và chỉ khi khóa (trường) đã tồn tại , vì vậy khi bạn thêm một trường mới vào tài liệu, đó là một thao tác lớn hơn là chỉ gán một giá trị khác cho một trường hiện có.
Tuy nhiên, ngay cả khi đó, các giá trị phải có cùng kích thước và không được thay đổi loại và chúng phải thuộc loại
double, long, int or bool
, nếu không thì không một bản cập nhật tại chỗ hiện tại.
Tôi không chắc phần sau thực sự quan trọng như thế nào trong thực tế , nhưng máy chủ chắc chắn sử dụng các đường dẫn mã hoàn toàn khác nhau cho cả hai, vì vậy, ví dụ, nó có thể dẫn đến việc sắp xếp lại trường. Đối với các tài liệu rất lớn, điều đó có thể dẫn đến sự khác biệt có thể đo lường được về hiệu suất.
Điều này cho thấy rằng $inc
rất khác ở chỗ nó chỉ cho phép các hoạt động chắc chắn được thực hiện tại chỗ, bởi vì $inc
chỉ hoạt động trên các kiểu số và không thể thay đổi kích thước hoặc kiểu một cách tự nhiên.