我有一個MongoDB的版本3.0.3收集其中包含的文件有2場:MongoDB中不使用多鍵索引
- 一個數字長ID
- 60個數字雙打的數組。
我在數組上建立了一個多鍵索引,並通過使用getIndexInfo()
方法確認索引存在並且是多鍵。但是,當我查詢數組中兩個特定字段的交集時,Mongo不使用此索引,儘管集合中有1,000,000個文檔。我可以從explain()
方法的輸出中看到這一點。更奇怪的是,當我指定使用hint
索引時,Mongo遍歷所有1,000,000個文檔和60,000,000個索引條目,我在explain()
的輸出中看到這些條目。
我建設用下面的代碼查詢:
BasicDBObject q2 = new BasicDBObject("array.0",new BasicDBObject("$lt",1000.0));
BasicDBObject q1 = new BasicDBObject("array.1",new BasicDBObject("$gte",800.0));
BasicDBObject q_and = new BasicDBObject("$and",Arrays.asList(q1,q2));
dbo = collection.find(q_and).explain();
有什麼想法?
在此先感謝您的幫助。
在答覆爲解釋輸出請求:
不指定一個提示,解釋輸出如下:
{ "queryPlanner" :
{ "plannerVersion" : 1 , "namespace" : "local.TestArrays" , "indexFilterSet" : false , "parsedQuery" :
{ "$and" : [
{ "array.0" :
{ "$lt" : 1000.0
}
} ,
{ "array.1" :
{ "$gte" : 800.0
}
}]
} , "winningPlan" :
{ "stage" : "COLLSCAN" , "filter" :
{ "$and" : [
{ "array.0" :
{ "$lt" : 1000.0
}
} ,
{ "array.1" :
{ "$gte" : 800.0
}
}]
} , "direction" : "forward"
} , "rejectedPlans" : [ ]
} , "executionStats" :
{ "executionSuccess" : true , "nReturned" : 2 , "executionTimeMillis" : 2248 , "totalKeysExamined" : 0 , "totalDocsExamined" : 1000000 , "executionStages" :
{ "stage" : "COLLSCAN" , "filter" :
{ "$and" : [
{ "array.0" :
{ "$lt" : 1000.0
}
} ,
{ "array.1" :
{ "$gte" : 800.0
}
}]
} , "nReturned" : 2 , "executionTimeMillisEstimate" : 2190 , "works" : 1000002 , "advanced" : 2 , "needTime" : 999999 , "needFetch" : 0 , "saveState" : 7812 , "restoreState" : 7812 , "isEOF" : 1 , "invalidates" : 0 , "direction" : "forward" , "docsExamined" : 1000000
} , "allPlansExecution" : [ ]
} , "serverInfo" :
{ "host" : "NYDEVWS0005052" , "port" : 27017 , "version" : "3.0.3" , "gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105"
}
}
當指定索引用下面的代碼的使用方法:
collection.find(q_and).hint(「array_1」)。explain();
解釋輸出如下:
{ "queryPlanner" :
{ "plannerVersion" : 1 , "namespace" : "local.TestArrays" , "indexFilterSet" : false , "parsedQuery" :
{ "$and" : [
{ "array.0" :
{ "$lt" : 1000.0
}
} ,
{ "array.1" :
{ "$gte" : 800.0
}
}]
} , "winningPlan" :
{ "stage" : "KEEP_MUTATIONS" , "inputStage" :
{ "stage" : "FETCH" , "filter" :
{ "$and" : [
{ "array.0" :
{ "$lt" : 1000.0
}
} ,
{ "array.1" :
{ "$gte" : 800.0
}
}]
} , "inputStage" :
{ "stage" : "IXSCAN" , "keyPattern" :
{ "array" : 1
} , "indexName" : "array_1" , "isMultiKey" : true , "direction" : "forward" , "indexBounds" :
{ "array" : [ "[MinKey, MaxKey]"]
}
}
}
} , "rejectedPlans" : [ ]
} , "executionStats" :
{ "executionSuccess" : true , "nReturned" : 2 , "executionTimeMillis" : 61401 , "totalKeysExamined" : 60000000 , "totalDocsExamined" : 1000000 , "executionStages" :
{ "stage" : "KEEP_MUTATIONS" , "nReturned" : 2 , "executionTimeMillisEstimate" : 56570 , "works" : 60001744 , "advanced" : 2 , "needTime" : 59999998 , "needFetch" : 1743 , "saveState" : 470130 , "restoreState" : 470130 , "isEOF" : 1 , "invalidates" : 0 , "inputStage" :
{ "stage" : "FETCH" , "filter" :
{ "$and" : [
{ "array.0" :
{ "$lt" : 1000.0
}
} ,
{ "array.1" :
{ "$gte" : 800.0
}
}]
} , "nReturned" : 2 , "executionTimeMillisEstimate" : 55620 , "works" : 60001744 , "advanced" : 2 , "needTime" : 59999998 , "needFetch" : 1743 , "saveState" : 470130 , "restoreState" : 470130 , "isEOF" : 1 , "invalidates" : 0 , "docsExamined" : 1000000 , "alreadyHasObj" : 0 , "inputStage" :
{ "stage" : "IXSCAN" , "nReturned" : 1000000 , "executionTimeMillisEstimate" : 50820 , "works" : 60000000 , "advanced" : 1000000 , "needTime" : 59000000 , "needFetch" : 0 , "saveState" : 470130 , "restoreState" : 470130 , "isEOF" : 1 , "invalidates" : 0 , "keyPattern" :
{ "array" : 1
} , "indexName" : "array_1" , "isMultiKey" : true , "direction" : "forward" , "indexBounds" :
{ "array" : [ "[MinKey, MaxKey]"]
} , "keysExamined" : 60000000 , "dupsTested" : 60000000 , "dupsDropped" : 59000000 , "seenInvalidated" : 0 , "matchTested" : 0
}
}
} , "allPlansExecution" : [ ]
} , "serverInfo" :
{ "host" : "NYDEVWS0005052" , "port" : 27017 , "version" : "3.0.3" , "gitVersion" : "b40106b36eecd1b4407eb1ad1af6bc60593c6105"
}
}
你如何在java驅動中使用'hint'?而且還可以運行在蒙戈殼相同的查詢和發佈的輸出'解釋()'? – bagrat
這說明,當我不指定提示的輸出: –
請包括它在後 – bagrat