簡體   English   中英

雖然設置了索引,但簡單的MongoDB查詢非常慢

[英]Simple MongoDB query very slow although index is set

我有一個包含大約100M文檔的MongoDB集合。

文件基本上如下:

_id             : ObjectId("asd1234567890")
_reference_1_id : ObjectId("fgh4567890123")
_reference_2_id : ObjectId("jkl7890123456")
name            : "Test1"
id              : "4815162342"
created_time    : Date( 1331882436000 )
_contexts       : ["context1", "context2"]
...

設置了一些索引,這里是db.mycoll.getIndexes()的輸出;

[
{
    "v" : 1,
    "key" : {
        "_id" : 1
    },
    "ns" : "mydb.mycoll",
    "name" : "_id_"
},
{
    "v" : 1,
    "key" : {
        "_reference_1_id" : 1,
        "_reference_2_id" : 1,
        "id" : 1
    },
    "unique" : true,
    "ns" : "mydb.mycoll",
    "name" : "_reference_1_id_1__reference_2_id_1_id_1"
},
{
    "v" : 1,
    "key" : {
        "_reference_1_id" : 1,
        "_reference_2_id" : 1,
        "_contexts" : 1,
        "created_time" : 1
    },
    "ns" : "mydb.mycoll",
    "name" : "_reference_1_id_1__reference_2_id_1__contexts_1_created_time_1"
}
]

當我執行像這樣的查詢時

db.mycoll.find({"_reference_2_id" : ObjectId("jkl7890123456")})

無論是否有結果,它都需要一個多小時(!)才能完成。 有任何想法嗎?

更新:這是輸出的內容

db.mycoll.find({"_reference_2_id" : ObjectId("jkl7890123456")}).explain();

看起來像:

{
"cursor" : "BasicCursor",
"nscanned" : 99209163,
"nscannedObjects" : 99209163,
"n" : 5007,
"millis" : 5705175,
"nYields" : 17389,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {

}
}

你沒有任何mongo會自動使用的索引,所以它正在進行全表掃描。

文檔所述

如果查詢中不存在[索引]的第一個鍵,則僅在顯式提示時才使用索引。

為什么

如果在A,B有一個索引-你通過搜索a單獨-索引將自動使用。 這是因為它是索引的開始(這很快),db可以忽略索引值的其余部分。

單獨使用b進行搜索時,a,b上的索引效率很低 ,因為它無法使用“以thisfixedstring開頭”來使用索引搜索。

那么,要么:

  • 在查詢中包含_reference_1_id(可能不相關)
  • 或者在_reference_2_id上添加索引(如果您經常按字段查詢)
  • 或使用提示

暗示

可能是您現在最低成本的選擇。

添加查詢提示以強制使用_reference_1_id_1__reference_2_id_1_id_1索引。 這可能比全表掃描快得多,但仍然比從您在查詢中使用的字段開始的索引慢很多。

db.mycoll
    .find({"_reference_2_id" : ObjectId("jkl7890123456")})
    .hint("_reference_1_id_1__reference_2_id_1_id_1");

是的,我在相同數量的數據上安靜了同樣的問題。 在文檔中,編寫了帶索引的查詢必須符合ram。 我認為情況並非如此,查詢必須先做很多磁盤訪問才能先檢索索引然后獲取值。 在您的情況下,直接收集讀取將更快。

EV。

我會嘗試在_reference_2_id上設置一個非唯一索引,因為目前我懷疑你將完全相當於全表掃描,即使索引包含_reference_2_id ,它們也不會被使用(見這里 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM