MongoDB的學習(3)--索引

來源:互聯網
上載者:User

標籤:

索引可以用來最佳化查詢,而且在某些特定類型的查詢中,索引是必不可少的。為集合選擇合適的索引是提高效能的關鍵。

先來mock資料

for (i = 0; i < 1000000; i++) {    db.users.insert({        "i": i,        "username": "user" + i,        "age": Math.floor(Math.random() * 120),        "created": new Date()    });}

資料庫中會建立一百萬條資料,稍微有點慢,需要等會。

我們可以使用explain()函數查看MongoDB在執行查詢的過程中所做的事情。執行如下命令,尋找使用者名稱為user1000的使用者。

db.users.find({username:"user1000"}).explain()

得到結果如下:

{    "cursor" : "BasicCursor",    "isMultiKey" : false,    "n" : 1,    "nscannedObjects" : 1000000,    "nscanned" : 1000000,    "nscannedObjectsAllPlans" : 1000000,    "nscannedAllPlans" : 1000000,    "scanAndOrder" : false,    "indexOnly" : false,    "nYields" : 7813,    "nChunkSkips" : 0,    "millis" : 411,    "server" : "user:27017",    "filterSet" : false}

之後會詳細介紹各個欄位的意思,現在我們只需要知道,"n"表示查詢結果的數量,"nscanned"表示MongoDB在完成這個查詢的過程中掃描的檔案總數,"millis"表示這個查詢耗費的毫秒數。可以看到,為了尋找user1000,MongoDB遍曆了整個集合,消耗了411毫秒。

為了最佳化查詢,我們可以在尋找到一個結果的時候,就結束查詢,返回結果。命令如下:

db.users.find({username:"user1000"}).limit(1).explain()

結果如下:

{    "cursor" : "BasicCursor",    "isMultiKey" : false,    "n" : 1,    "nscannedObjects" : 1001,    "nscanned" : 1001,    "nscannedObjectsAllPlans" : 1001,    "nscannedAllPlans" : 1001,    "scanAndOrder" : false,    "indexOnly" : false,    "nYields" : 7,    "nChunkSkips" : 0,    "millis" : 1,    "server" : "user:27017",    "filterSet" : false}

可以看到掃描文檔數和消耗時間都變少了很多,但是如果我們要尋找user999999,MongoDB還是要遍曆集合才能找到。而且隨著使用者數量的增多,查詢會越來越慢。

對於這種情況,建立索引是一個非常好的解決方案:索引可以根據給定的欄位組織資料,讓MongoDB能夠非常快速的找到目的文件。使用如下命令,在username欄位上建立一個索引。

db.users.ensureIndex({"username":1})

然後再來執行一下之前執行過的語句

db.users.find({username:"user1000"}).explain()

其結果如下:

{    "cursor" : "BtreeCursor username_1",    "isMultiKey" : false,    "n" : 1,    "nscannedObjects" : 1,    "nscanned" : 1,    "nscannedObjectsAllPlans" : 1,    "nscannedAllPlans" : 1,    "scanAndOrder" : false,    "indexOnly" : false,    "nYields" : 0,    "nChunkSkips" : 0,    "millis" : 0,    "indexBounds" : {        "username" : [            [                "user1000",                "user1000"            ]        ]    },    "server" : "user:27017",    "filterSet" : false}

然後你會發現查詢變快了很多,幾乎是瞬間完成,這就是使用索引的效果。但是索引也是有代價的,對於添加的每一個索引,每次寫操作(插入、更新、刪除)都將耗費更多的時間。這是因為當資料發生變動時,MongoDB不僅要更新文檔,還要更新集合上的所有索引。因此,MongoDB限制每個集合上最多隻能有64個索引。通常,在一個特定的集合上,不應該擁有兩個以上的索引。

 當一個索引建立在多個欄位上時,我們稱它為複合索引,建立的語句如下:

db.users.ensureIndex({"age":1, "username":1})

 如果查詢中有多個排序方向或者查詢條件中有多個鍵,複合索引就會非常有用。

MongoDB對這個索引的使用方法取決於查詢的類型。下面是三種主要的方式。

第一種:

db.users.find({"age":21}).sort({"username":-1})

這是一個點查詢,用於尋找單個值(儘管包含這個值的文檔是多個)。由於索引中的第二個欄位,查詢結果已經是有序的了。這種類型的查詢是非常高效的。

第二種:

db.users.find({"age":{"$gte":21,"$lte":30}})

這是一個多值查詢,尋找到多個值相匹配的文檔,MongoDB會使用索引中的第一個鍵“age”得到匹配文檔。如果使用“username”做查詢,該索引不起作用。

第三種:

db.users.find({"age":{"$gte":21,"$lte":30}}).sort({"username":1})

這也是一個多值查詢,與上一個類似,只是這次需要對查詢結果進行排序。MongoDB需要在記憶體中對結果進行排序,不如上一個高效。

刪除索引的命令如下:

db.users.dropIndex(‘age_1_username_1‘)

刪除users集合中名字為‘age_1_username_1‘的索引。

所有資料庫的索引資訊都儲存在system.indexes集合中,這是一個保留集合,不能在其中插入或者刪除文檔,只能通過ensureIndex和dropIndex對其進行操作。

使用如下命令可以擷取users集合上的索引資訊:

db.users.getIndexes()

結果如下:

[    {        "v" : 1,        "key" : {            "_id" : 1        },        "name" : "_id_",        "ns" : "test.users"    },    {        "v" : 1,        "key" : {            "username" : 1        },        "name" : "username_1",        "ns" : "test.users"    },    {        "v" : 1,        "key" : {            "age" : 1,            "username" : 1        },        "name" : "age_1_username_1",        "ns" : "test.users"    }]

 

MongoDB的學習(3)--索引

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.