2012-04-18 25 views
7

Sự kiện thu thập có userId và một mảng sự kiện-- mỗi phần tử trong mảng là tài liệu được nhúng. Ví dụ:mongodb - chỉ mục ngày không được sử dụng

{ 
    "_id" : ObjectId("4f8f48cf5f0d23945a4068ca"), 
    "events" : [ 
      { 
        "eventType" : "profile-updated", 
        "eventId" : "247266", 
        "eventDate" : ISODate("1938-04-27T23:05:51.451Z"), 
      }, 
      { 
        "eventType" : "login", 
        "eventId" : "64531", 
        "eventDate" : ISODate("1948-05-15T23:11:37.413Z"), 
      } 
    ], 
    "userId" : "junit-19568842", 

}

Sử dụng một truy vấn như hình dưới đây tofind sự kiện được tạo ra trong 30 ngày qua:

db.events.find({ events : { $elemMatch: { "eventId" : 201, 
"eventDate" : {$gt : new Date(1231657163876) } } } } ).explain() 

kế hoạch truy vấn cho thấy chỉ số về "events.eventDate" được sử dụng khi dữ liệu thử nghiệm chứa ít sự kiện hơn (khoảng 20):

{ 
    "cursor" : "BtreeCursor events.eventDate_1", 
    "nscanned" : 0, 
    "nscannedObjects" : 0, 
    "n" : 0, 
    "millis" : 0, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : true, 
    "indexOnly" : false, 
    "indexBounds" : { 
      "events.eventDate" : [ 
        [ 
          ISODate("2009-01-11T06:59:23.876Z"), 
          ISODate("292278995-01--2147483647T07:12:56.808Z") 
        ] 
      ] 
    } 

}

Tuy nhiên, khi có số lượng lớn các sự kiện (khoảng 500), chỉ số không được sử dụng:

{ 
    "cursor" : "BasicCursor", 
    "nscanned" : 4, 
    "nscannedObjects" : 4, 
    "n" : 0, 
    "millis" : 0, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : false, 
    "indexOnly" : false, 
    "indexBounds" : { 

    } 

}

Tại sao chỉ số không được sử dụng khi có rất nhiều các sự kiện? Có thể là khi có số lượng lớn các sự kiện, MongoDB thấy hiệu quả chỉ là quét tất cả các mục so với sử dụng chỉ mục?

+0

Bạn đang phàn nàn rằng trình tối ưu hóa không sử dụng chỉ mục trên truy vấn mất 0ms để trả lại? :) –

+0

Đầu ra giải nghĩa ở trên là từ một bộ sưu tập thử nghiệm. Với khoảng 20 triệu tài liệu, truy vấn mất khoảng 8 giây. – dsatish

+0

Các truy vấn phạm vi như vậy có thể chậm nếu bạn đang truy vấn một phần đáng kể tài liệu của bộ sưu tập. Bạn có thể sử dụng gợi ý để buộc chỉ mục so sánh tốc độ, nhưng tôi tưởng tượng nó sẽ chỉ làm chậm quá trình quét chỉ mục. Bạn nên đăng giải thích từ dữ liệu sản xuất của mình, có và không có gợi ý. Vấn đề là, nếu bạn đang tìm kiếm vài triệu tài liệu phù hợp, nó sẽ mất một thời gian để kiểm tra chúng. –

Trả lời

11

Trình tối ưu hóa truy vấn của MongoDB hoạt động theo cách đặc biệt. Thay vì tính toán chi phí của kế hoạch truy vấn nhất định, nó chỉ ra mắt tất cả các gói có sẵn. Cho dù trở về đầu tiên được coi là tối ưu và sẽ được sử dụng trong tương lai.

Ứng dụng phát triển, dữ liệu phát triển và thay đổi, kế hoạch tối ưu có thể trở nên không tối ưu tại một số điểm. Vì vậy, mongo lặp lại quá trình lựa chọn truy vấn đó một lần trong một thời gian.

Dường như trong trường hợp cụ thể này, quét cơ bản là hiệu quả nhất.

Link: http://www.mongodb.org/display/DOCS/Query+Optimizer

2

Sử dụng $ gợi ý để buộc sử dụng chỉ số "events.eventDate", các nscannedObjects là hơn w/o chỉ số.

Pseudo mã khi sử dụng chỉ số:

for(all entries in index matching the criteria) { 
    get user object and scan to see if the eventId criteria is met 
} 

tất cả các mục trong chỉ số phù hợp với các tiêu chuẩn -> mỗi sự kiện là một mục trong chỉ mục. Vì vậy, số lượng mục trong chỉ mục sẽ nhiều hơn số lượng người dùng. Giả sử có 4 đối tượng người dùng và tổng số 7 sự kiện phù hợp với tiêu chí, đối tượng người dùng được quét 7 lần (đối với vòng lặp được thực thi 7 lần). Khi chỉ mục không được quét, tất cả 4 đối tượng người dùng chỉ được kiểm tra một lần. Vì vậy, việc sử dụng chỉ mục, số lần đối tượng người dùng được quét nhiều hơn khi không sử dụng chỉ mục. Sự hiểu biết này có đúng không?

db.events.find({ events : { $elemMatch: { "eventId" : 201, 
"eventDate" : {$gt : new Date(1231657163876) } } } } ) 
._addSpecial("$hint",{"events.eventDate":1}).explain() 

{ 
    "cursor" : "BasicCursor", 
    "nscanned" : 7, 
    "nscannedObjects" : 7, 
    "n" : 0, 
    "millis" : 0, 
    "nYields" : 0, 
    "nChunkSkips" : 0, 
    "isMultiKey" : false, 
    "indexOnly" : false, 
    "indexBounds" : { 

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