2015-02-06 19 views
24

Tôi có một bộ sưu tập mongoDB với hàng triệu hàng và tôi đang cố gắng tối ưu hóa các truy vấn của mình. Tôi hiện đang sử dụng khung tổng hợp để truy xuất dữ liệu và nhóm chúng theo ý muốn. Truy vấn tập hợp điển hình của tôi giống như sau: $match > $group > $ group > $project

Tuy nhiên, tôi nhận thấy rằng các phần cuối cùng chỉ mất vài ms, khởi đầu là chậm nhất.

Tôi đã cố thực hiện truy vấn chỉ với bộ lọc $ phù hợp, và sau đó thực hiện cùng một truy vấn với collection.find. Truy vấn tổng hợp mất ~ 80ms trong khi truy vấn tìm kiếm mất 0 hoặc 1ms.

Tôi có chỉ mục trên khá nhiều trường nên tôi đoán đây không phải là vấn đề. Bất kỳ ý tưởng về những gì có thể đi sai? Hay nó chỉ là một nhược điểm "bình thường" của khung tổng hợp?

Tôi có thể sử dụng truy vấn tìm kiếm thay vì truy vấn tổng hợp, tuy nhiên tôi sẽ phải thực hiện nhiều xử lý sau khi yêu cầu và quá trình này có thể được thực hiện nhanh chóng với $group v.v.

Cảm ơn,

EDIT:

Đây là tiêu chí của tôi:

{ 
    "action" : "click", 
    "timestamp" : { 
      "$gt" : ISODate("2015-01-01T00:00:00Z"), 
      "$lt" : ISODate("2015-02-011T00:00:00Z") 
    }, 
    "itemId" : "5" 
} 
+0

Bạn có thể đăng '$ match' của mình và tìm không?Trong hầu hết các tập quán, một '$ match' và một tìm kiếm phải tương đương nhưng tôi muốn xem chính xác những gì bạn đang so sánh với câu trả lời chính xác. Ngoài ra, bạn có chạy tập hợp đầu tiên và sau đó tìm? Điều gì sẽ xảy ra nếu bạn lặp lại hai lần lặp lại và so sánh thời gian? Sự khác biệt có thể là chi phí di chuyển các kết quả vào bộ nhớ từ đĩa. – wdberkeley

+0

Tôi đã thêm tiêu chí vào bài đăng đầu tiên, tuy nhiên ngay cả khi không có tiêu chí dấu thời gian, tôi thấy một khoảng cách lớn. Nhưng bây giờ tôi tự hỏi nếu nó không liên quan đến thực tế là find() trả về một con trỏ và chỉ hiển thị các kết quả đầu tiên. – Owumaro

+7

Ok, tôi đã có rất nhiều chỉ mục vô ích vì vậy tôi đã làm sạch mọi thứ và chỉ tạo một chỉ mục hợp chất (với các trường của bộ lọc $ match của tôi). Bây giờ tôi có hiệu suất tốt và cùng một màn trình diễn để tìm và tổng hợp với $ match :) Vấn đề được giải quyết. – Owumaro

Trả lời

14

Mục đích chính của aggregation framework là để giảm bớt các truy vấn của một số lượng lớn các mục và tạo ra một số lượng thấp kết quả giữ giá trị cho bạn.

Như bạn đã nói, bạn cũng có thể sử dụng nhiều truy vấn find, nhưng hãy nhớ rằng bạn không thể tạo trường mới với các truy vấn find. Mặt khác, giai đoạn $group cho phép bạn xác định các trường mới của mình.

Nếu bạn muốn đạt được chức năng của aggregation framework, bạn rất có thể phải chạy một số find ban đầu (hoặc chuỗi một số), kéo thông tin đó và thao tác thêm bằng ngôn ngữ lập trình.

aggregation pipeline có vẻ mất nhiều thời gian hơn, nhưng ít nhất bạn biết bạn chỉ phải tính đến hiệu suất của một hệ thống - công cụ MongoDB.

Trong khi, khi thao tác với dữ liệu được trả về từ truy vấn find, bạn có thể phải thao tác dữ liệu bằng ngôn ngữ lập trình hơn, do đó làm tăng độ phức tạp tùy thuộc vào sự phức tạp của ngôn ngữ lập trình được lựa chọn.

+9

Cảm ơn thông tin. Tuy nhiên, tôi vẫn không hiểu tại sao truy vấn tổng hợp chỉ có bộ lọc $ match không nhanh bằng truy vấn tìm kiếm đơn giản với cùng một bộ lọc. – Owumaro

3

Bạn đã thử sử dụng giải thích() cho các truy vấn tìm kiếm của mình chưa? Nó sẽ cung cấp cho bạn ý tưởng tốt về bao nhiêu thời gian tìm() truy vấn chính xác sẽ mất. Bạn có thể làm tương tự cho $ khớp với $ giải thích & xem liệu có sự khác biệt nào trong chỉ số truy cập & các thông số khác không.

Ngoài ra, phần nhóm $ của khung tổng hợp không sử dụng tính năng lập chỉ mục để nó phải xử lý tất cả các bản ghi được trả về bởi giai đoạn kết hợp $ của khung tổng hợp. Vì vậy, để hiểu rõ hơn về hoạt động của truy vấn của bạn, hãy xem tập kết quả trả về & cho dù nó phù hợp với bộ nhớ để được xử lý bởi MongoDB hay không.

Các vấn đề liên quan