1. 程式人生 > 實用技巧 >【趙強老師】MongoDB中的索引(上)

【趙強老師】MongoDB中的索引(上)

索引是提高查詢查詢效率最有效的手段。索引是一種特殊的資料結構,索引以易於遍歷的形式儲存了資料的部分內容(如:一個特定的欄位或一組欄位值),索引會按一定規則對儲存值進行排序,而且索引的儲存位置在記憶體中,所在從索引中檢索資料會非常快。如果沒有索引,MongoDB必須掃描集合中的每一個文件,這種掃描的效率非常低,尤其是在資料量較大時。

一、索引的基礎知識

下面以關係型資料庫Oracle為例,介紹索引的基本原理,如下圖所示:

從上圖可以看成,索引的本質其實就相當於是一本書的目錄。當查詢表中資料的時候,先查詢目錄(索引)中的行地址,再通過行地址查詢到表中的資料,從而提高查詢的效能。

下圖說明了在MongoDB中,索引在查詢和排序中是如何工作的?

通過這個例子,可以清楚的看到索引儲存的是一個特定欄位或者幾個欄位的集合,並且按照一定的規律排序。當建立集合的時候,MongoDB自動在_id上建立一個唯一性索引,由於是唯一性的,所以可以防止重複的_id值插入到集合中。通過getIndexes可以查詢到MongoDB集合上的索引資訊,如下圖所示。

當沒有索引的時候,通過檢視執行計劃,可以看到查詢的過程,如下:查詢:10號部門,工資小於3000的文件。

那麼如何建立一個簡單的索引呢?注意從mongoDB 3.0開始ensureIndex被廢棄,今後都僅僅是db.collection.createIndex的一個別名。

現在在deptno和sal上建立一個索引,並重新檢視執行計劃:db.emp.createIndex({"deptno":1,"sal":-1})

注意:除了可以使用explain()生成執行計劃外,還可以有幾個可選的引數,如下:
.explain("allPlansExecution")
.explain("executionStats")
.explain("queryPlanner")

二、索引的型別一:單鍵索引(Single Field)

單鍵索引是最普通的索引,與_id索引不同,單鍵索引不會自動建立。

準備資料:
db.testindex1.insert({"_id":1,"zipcode":1034,"location":{state:"NY",city:"New York"}})

在單個列上建立單鍵索引:
db.testindex1.createIndex({"zipcode":1})

在巢狀的列上建立單鍵索引
db.testindex1.createIndex({"location:state":1})

在內嵌的文件上建立單鍵索引
db.testindex1.createIndex({"location":-1})
這樣將會把location作為一個整體。

三、索引的型別二:多鍵索引(Multikey Index)

多鍵索引與單鍵索引建立形式相同,區別在於欄位的值。值具有多個記錄,如陣列。

如上圖,基於集合上的陣列建立多鍵索引,且陣列為內嵌文件。

準備資料:
db.testindex2.insertMany([
{ _id: 5, type: "food", item: "aaa", ratings: [ 5, 8, 9 ] },
{ _id: 6, type: "food", item: "bbb", ratings: [ 5, 9 ] },
{ _id: 7, type: "food", item: "ccc", ratings: [ 9, 5, 8 ] },
{ _id: 8, type: "food", item: "ddd", ratings: [ 9, 5 ] },
{ _id: 9, type: "food", item: "eee", ratings: [ 5, 9, 5 ] }])

下面基於ratings列建立一個多鍵索引:
db.testindex2.createIndex( { ratings: 1 } )

查詢陣列上為5,9的文件
db.testindex2.find( { ratings: [ 5, 9 ] } )

下面檢視其執行計劃
db.testindex2.find( { ratings: [ 5, 9 ] } ).explain()