Phép chiếu mongoDB ảnh hưởng đến hiệu suất như thế nào?


10

Từ MongoDBtài liệu được đề cập rằng:

Khi bạn chỉ cần một tập hợp con của các trường từ tài liệu, bạn có thể đạt được hiệu suất tốt hơn bằng cách chỉ trả lại các trường bạn cần

Làm thế nào các lĩnh vực lọc ảnh hưởng đến hiệu suất? Hiệu suất có liên quan đến kích thước của dữ liệu được truyền qua mạng không? hoặc kích thước của dữ liệu sẽ được giữ trong bộ nhớ? Làm thế nào chính xác hiệu suất này được cải thiện? Hiệu suất này được đề cập trong tài liệu là gì?

Tôi có các truy vấn MongoDB chậm. Việc trả về một tập hợp con có ảnh hưởng đến truy vấn chậm của tôi không (tôi có chỉ mục ghép trên trường)?


Không có mã, bạn không thể đề xuất cho bạn. những gì thực sự sẽ ảnh hưởng đến hiệu suất trong truy vấn chiếu "MongoDB". Luôn luôn tốt hơn ít nhất là bạn đề cập đến mã.
Md Haidar Ali Khan

@MdHaidarAliKhan không phải là về mã và tải trọng của tôi. Tôi chỉ muốn biết tại sao mongoDB nói rằng việc lọc ảnh hưởng đến hiệu suất? Từ quan điểm nào hiệu suất này đã được đo lường? Ví dụ, nó giúp ích cho việc sử dụng bộ nhớ của Mongo vì ít dữ liệu hơn hoặc ít IO hơn (ví dụ), v.v.
ALH

Tôi chỉ muốn biết tại sao mongoDB nói rằng việc lọc ảnh hưởng đến hiệu suất? tốt, sử dụng các phép chiếu để trả về dữ liệu cần thiết, ý tôi là nói rằng bạn có thể đạt được hiệu suất tốt hơn bằng cách chỉ trả lại các trường bạn cần. Ví dụ: db.posts.find ({}, {}). Sort ({}).
Md Haidar Ali Khan

, Ví dụ, nó có giúp ích cho việc sử dụng bộ nhớ của Mongo vì ít dữ liệu hơn hoặc ít IO hơn (ví dụ), v.v., bạn có thể cập nhật phiên bản MongoDB và hệ điều hành nào trong môi trường của bạn không?
Md Haidar Ali Khan

@MdHaidarAliKhan OS là Debian 8,MongoDB 3.6.2
ALH

Câu trả lời:


15

Theo mặc định, các truy vấn trả về tất cả các trường trong các tài liệu phù hợp. Nếu bạn cần tất cả các trường, việc trả lại tài liệu đầy đủ sẽ hiệu quả hơn so với việc máy chủ thao tác tập kết quả với tiêu chí chiếu.

Tuy nhiên, sử dụng phép chiếu để giới hạn các trường để trả về từ kết quả truy vấn có thể cải thiện hiệu suất bằng cách:

  • xóa các trường không cần thiết khỏi kết quả truy vấn (tiết kiệm băng thông mạng)
  • giới hạn các trường kết quả để đạt được một truy vấn được bảo hiểm (trả về kết quả truy vấn được lập chỉ mục mà không tìm nạp tài liệu đầy đủ)

Khi sử dụng phép chiếu để loại bỏ các trường không sử dụng, máy chủ MongoDB sẽ phải tìm nạp từng tài liệu đầy đủ vào bộ nhớ (nếu nó chưa có) và lọc kết quả để trả về. Việc sử dụng phép chiếu này không làm giảm mức sử dụng bộ nhớ hoặc bộ làm việc trên máy chủ MongoDB, nhưng có thể tiết kiệm băng thông mạng đáng kể cho kết quả truy vấn tùy thuộc vào mô hình dữ liệu của bạn và các trường được chiếu.

Truy vấn được bảo hiểm là trường hợp đặc biệt trong đó tất cả các trường được yêu cầu trong kết quả truy vấn được bao gồm trong chỉ mục được sử dụng, do đó máy chủ không phải tìm nạp toàn bộ tài liệu. Các truy vấn được bảo hiểm có thể cải thiện hiệu suất (bằng cách tránh tìm nạp tài liệu) và sử dụng bộ nhớ (nếu các truy vấn khác không yêu cầu tìm nạp cùng một tài liệu).

Ví dụ

Đối với mục đích trình diễn qua mongoshell, hãy tưởng tượng bạn có một tài liệu trông như thế này:

db.data.insert({
    a: 'webscale',
    b: new Array(10*1024*1024).join('z')
})

Trường bcó thể đại diện cho một lựa chọn các giá trị (hoặc trong trường hợp này là một chuỗi rất dài).

Tiếp theo, tạo một chỉ mục trên {a:1}đó là trường thường được sử dụng theo trường hợp sử dụng của bạn:

db.data.createIndex({a:1})

Một đơn giản findOne()không có tiêu chí chiếu trả về kết quả truy vấn khoảng 10MB:

> bsonsize(db.data.findOne({}))
10485805

Thêm phép chiếu {a:1}sẽ giới hạn đầu ra cho trường avà tài liệu _id(được bao gồm theo mặc định). Máy chủ MongoDB vẫn đang thao tác một tài liệu 10 MB để chọn hai trường, nhưng kết quả truy vấn hiện chỉ có 33 byte:

> bsonsize(db.data.findOne({}, {a:1}))
33

Truy vấn này không được bảo hiểm vì tài liệu đầy đủ phải được tìm nạp để khám phá _idgiá trị. Các _idlĩnh vực được đưa vào truy vấn kết quả theo mặc định vì nó là định danh duy nhất cho một tài liệu, nhưng _idsẽ không được tính vào chỉ số thứ trừ thêm một cách rõ ràng.

Các số liệu totalDocsExaminedvà kết quả totalKeysExaminedtrong explain()kết quả sẽ cho thấy có bao nhiêu tài liệu và khóa chỉ mục đã được kiểm tra:

 > db.data.find(
     {a:'webscale'}, 
     {a:1}
 ).explain('executionStats').executionStats.totalDocsExamined
 > 1

Truy vấn này có thể được cải thiện bằng cách sử dụng phép chiếu để loại trừ _idtrường và đạt được một truy vấn được bảo hiểm chỉ sử dụng chỉ {a:1}mục. Truy vấn được bảo hiểm không còn cần phải tải tài liệu ~ 10 MB vào bộ nhớ, do đó sẽ hiệu quả trong cả việc sử dụng mạng và bộ nhớ:

 > db.data.find(
     {a:'webscale'},
     {a:1, _id:0}
 ).explain('executionStats').executionStats.totalDocsExamined
 0

 > bsonsize(db.data.findOne( {a:'webscale'},{a:1, _id:0}))
 21

Tôi có các truy vấn MongoDB chậm. Việc trả về một tập hợp con có ảnh hưởng đến truy vấn chậm của tôi không (tôi có chỉ mục ghép trên trường)?

Điều này không thể trả lời được nếu không có ngữ cảnh của một truy vấn cụ thể, tài liệu mẫu và đầu ra giải thích đầy đủ. Tuy nhiên, bạn có thể chạy một số điểm chuẩn trong môi trường của riêng mình cho cùng một truy vấn có và không có phép chiếu để so sánh kết quả. Nếu dự báo của bạn đang thêm chi phí đáng kể vào thời gian thực hiện truy vấn tổng thể (xử lý và chuyển kết quả), đây có thể là một gợi ý mạnh mẽ rằng mô hình dữ liệu của bạn có thể được cải thiện.

Nếu không rõ tại sao một truy vấn chậm, tốt nhất nên đăng một câu hỏi mới với các chi tiết cụ thể để điều tra.


1
Tôi thực sự đánh giá cao cho lời giải thích kỹ lưỡng của vấn đề. Có vẻ như không thể có các truy vấn được bảo hiểm vì phản hồi của tôi có nhiều dữ liệu hơn bên trong chỉ mục. Câu hỏi chính của tôi là ở đây, tôi sẽ rất vui nếu bạn có thể xem: dba.stackexchange.com/questions/195065/ mẹo
ALH

1

Với một phép chiếu, bạn có thể đạt được một tình huống trong đó tập kết quả đến trực tiếp từ chỉ mục.

Nếu bạn có chỉ số ghép {x:1, y:1, z:1}trong đó không có x, y, z nào là _id, bạn cần phải chiếu {_id:0, x:1, y:1, z:1}_idluôn được trả về như một phần của tập kết quả (khi nó không được chiếu đi) và công cụ cần phải đọc các tệp dữ liệu để có được nó. Điều này là do, chỉ mục không có giá trị _id, chỉ con trỏ đến tài liệu đó nơi lưu trữ giá trị.


Vì vậy, nếu tôi loại bỏ _idkhỏi phản hồi trả về, điều đó có phù hợp với RAM không? cái đó có giúp ích không?
ALH

1
MongoD (cố gắng) giữ ít nhất các chỉ mục trong bộ nhớ (và càng nhiều dữ liệu phù hợp). Nếu bạn truy vấn có thể được điền trực tiếp từ chỉ mục và bạn chiếu _id:0thì kết quả được trả về đầy đủ từ RAM, mà không cần đọc dữ liệu từ đĩa.
JJussi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.