Tôi có trang web sử dụng MongoDB để lưu trữ và truy xuất các số đo khác nhau. Đột nhiên, trong một số thời điểm, trang web của tôi trở nên quá chậm chạp, nó trở nên không sử dụng được. Hóa ra, cơ sở dữ liệu của tôi là thủ phạm.MongoDB: Truy vấn chậm, ngay cả với chỉ mục
Tôi đã tìm kiếm và không tìm thấy giải pháp nào cho vấn đề của mình, và tôi xin lỗi vì tôi khá mới với MongoDB và kéo tóc của tôi ra vào lúc này.
Phiên bản MongoDB tôi đang sử dụng là 2.4.6, trên máy ảo có RAM 20 GB, chạy máy chủ Ubuntu 12.04. Không có bản sao hoặc thiết lập sharding.
Thứ nhất, tôi đặt mức profiling tôi để 2 và nó cho thấy các truy vấn chậm nhất:
db.system.profile.find().sort({"millis":-1}).limit(1).pretty()
{
"op" : "query",
"ns" : "station.measurement",
"query" : {
"$query" : {
"e" : {
"$gte" : 0
},
"id" : "180"
},
"$orderby" : {
"t" : -1
}
},
"ntoreturn" : 1,
"ntoskip" : 0,
"nscanned" : 3295221,
"keyUpdates" : 0,
"numYield" : 6,
"lockStats" : {
"timeLockedMicros" : {
"r" : NumberLong(12184722),
"w" : NumberLong(0)
},
"timeAcquiringMicros" : {
"r" : NumberLong(5636351),
"w" : NumberLong(5)
}
},
"nreturned" : 0,
"responseLength" : 20,
"millis" : 6549,
"ts" : ISODate("2015-03-16T08:57:07.772Z"),
"client" : "127.0.0.1",
"allUsers" : [ ],
"user" : ""
}
Tôi chạy truy vấn cụ thể với .explain() và có vẻ như, nó sử dụng chỉ số như mong muốn, nhưng nó mất quá lâu. Tôi cũng chạy cùng một truy vấn trên máy chủ khác của tôi, máy chủ yếu hơn đáng kể và rút ra kết quả như một nhà vô địch trong một giây.
> db.measurement.find({"id":"180", "e":{$gte:0}}).sort({"t":-1}).explain()
{
"cursor" : "BtreeCursor id_1_t_-1_e_1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 660385,
"nscannedObjectsAllPlans" : 1981098,
"nscannedAllPlans" : 3301849,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 7,
"nChunkSkips" : 0,
"millis" : 7243,
"indexBounds" : {
"id" : [
[
"180",
"180"
]
],
"t" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"e" : [
[
0,
1.7976931348623157e+308
]
]
},
"server" : "station:27017"
}
Tiếp theo, tôi nhìn vào các chỉ số của đo bộ sưu tập và nó trông tốt với tôi:
> db.measurement.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "station.measurement",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"t" : 1
},
"ns" : "station.measurement",
"name" : "t_1"
},
{
"v" : 1,
"key" : {
"id" : 1,
"d" : 1,
"_id" : -1
},
"ns" : "station.measurement",
"name" : "id_1_d_1__id_-1"
},
{
"v" : 1,
"key" : {
"id" : 1,
"t" : -1,
"e" : 1
},
"ns" : "station.measurement",
"name" : "id_1_t_-1_e_1"
},
{
"v" : 1,
"key" : {
"id" : 1,
"t" : -1,
"e" : -1
},
"ns" : "station.measurement",
"name" : "id_1_t_-1_e_-1"
}
]
Đây cũng là phần còn lại của thông tin thu thập của tôi:
> db.measurement.stats()
{
"ns" : "station.measurement",
"count" : 157835456,
"size" : 22377799512,
"avgObjSize" : 141.77929395027692,
"storageSize" : 26476834672,
"numExtents" : 33,
"nindexes" : 5,
"lastExtentSize" : 2146426864,
"paddingFactor" : 1.0000000000028617,
"systemFlags" : 0,
"userFlags" : 0,
"totalIndexSize" : 30996614096,
"indexSizes" : {
"_id_" : 6104250656,
"t_1" : 3971369360,
"id_1_d_1__id_-1" : 8397896640,
"id_1_t_-1_e_1" : 6261548720,
"id_1_t_-1_e_-1" : 6261548720
},
"ok" : 1
}
Tôi đã thử thêm chỉ mục mới, sửa chữa toàn bộ cơ sở dữ liệu, reindex. Tôi đang làm gì sai? Tôi thực sự đánh giá cao sự giúp đỡ khi tôi tuyệt vọng chạy ra khỏi ý tưởng.
UPDATE 1:
tôi bổ sung thêm hai chỉ số theo đề nghị của Neil Lunn, một số các truy vấn là một Lot nhanh hơn:
{
"v" : 1,
"key" : {
"id" : 1,
"e" : 1,
"t" : -1
},
"ns" : "station.measurement",
"name" : "id_1_e_1_t_-1",
"background" : true
},
{
"v" : 1,
"key" : {
"id" : 1,
"e" : -1,
"t" : -1
},
"ns" : "station.measurement",
"name" : "id_1_e_-1_t_-1",
"background" : true
}
Kết quả tôi đã có được thú vị (không chắc chắn mặc dù chúng có liên quan)
Hai truy vấn tiếp theo khác với "id". Xin lưu ý, mỗi truy vấn sử dụng chỉ mục khác nhau, tại sao? Tôi có nên xóa những cái cũ hơn không?
> db.measurement.find({"id":"119", "e":{$gte:0}}).sort({"t":-1}).explain()
{
"cursor" : "BtreeCursor id_1_t_-1_e_1",
"isMultiKey" : false,
"n" : 840747,
"nscannedObjects" : 840747,
"nscanned" : 1047044,
"nscannedObjectsAllPlans" : 1056722,
"nscannedAllPlans" : 1311344,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 4,
"nChunkSkips" : 0,
"millis" : 3730,
"indexBounds" : {
"id" : [
[
"119",
"119"
]
],
"t" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
],
"e" : [
[
0,
1.7976931348623157e+308
]
]
},
"server" : "station:27017"
}
> db.measurement.find({"id":"180", "e":{$gte:0}}).sort({"t":-1}).explain()
{
"cursor" : "BtreeCursor id_1_e_1_t_-1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 0,
"nscanned" : 0,
"nscannedObjectsAllPlans" : 0,
"nscannedAllPlans" : 45,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"id" : [
[
"180",
"180"
]
],
"e" : [
[
0,
1.7976931348623157e+308
]
],
"t" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
},
"server" : "station:27017"
}
Sự cố có thể ở đâu khác không? Điều gì có thể gây ra "chậm chạp" đột ngột đó? Tôi có một số bộ sưu tập khác, nơi mà các truy vấn cũng đột ngột chậm hơn.
Ồ, và một điều khác. Trên máy chủ khác mà tôi có, các chỉ mục giống như ở đây trước khi tôi thêm các chỉ mục mới. Có, bộ sưu tập nhỏ hơn một chút nhưng nhanh hơn nhiều lần.
Cũng được hình thành như một câu hỏi. Tôi có vẻ như bạn đang quét nhiều mục "t" hơn "e". Là một thử nghiệm, hãy thử thay đổi chỉ mục và thứ tự truy vấn để đặt trọng tâm theo thứ tự vào "e" trước "t". Thay đổi tài liệu đề xuất điều này không nên thay đổi kết quả, nhưng kết quả của bạn sẽ rất thú vị để xem liệu có sự khác biệt hay không. –
Đề xuất thú vị, cảm ơn bạn! Tôi sẽ thêm các chỉ mục mới (id_1_e_1_t_-1 và id_1_e_-1_t_-1) và cho bạn biết về các kết quả này ngay sau khi các chỉ mục xây dựng sẽ mất một thời gian. – Denis
Xin chào, tôi đã xây dựng thành công các chỉ mục đó và thử nghiệm chúng với một số truy vấn. Tôi đã cập nhật câu hỏi của mình với kết quả :) – Denis