接下來幾篇我們將介紹 MongoDB 中的一個重要概念:Index 索引。索引的使用會讓我們進行查詢時有很大的影響。
在 MongoDB 中我們可以建立索引 Index,讓之後進行查詢時更有效率。如果查詢的欄位是已經有建立 Index 的欄位,MongoDB 就不會進去資料欄位,而是調出己經建好 B-tree 的 Index 來查詢。
我們使用以下指令進行查詢:db.collection.find({age: 30})
,MongoDB 預設使用 Collection Scan 去掃描整個 collection 來做查詢,但隨著 collection 數量增加,查詢的效率會降低。
而如果我們使用索引 Index,MongoDB 則會對查詢的欄位進行有序排列,且每個 index 都有 pointer 指向原先對應之 document。因此,在查詢時只會進行 Index Scan,進而提升查詢效率。
在 MongoDB 中,我們可以對每個欄位都建立索引,但會有相對的代價:
我們可以改成只針對查詢頻率高的欄位去建 index,但仍會犧牲部分的 insert 和 update 的效率。
首先我們先來介紹對單一欄位建立索引的方法,以下為範例資料:
index.json
[
{
"title": "After Dark in Central Park",
"year": 1900,
"cast": [],
"genres": []
},
...
{
"title": "Destroyer",
"year": 2018,
"cast": [
"Nicole Kidman",
"Tatiana Maslany",
"Sebastian Stan",
"Toby Kebbell",
"Scoot McNairy"
],
"genres": [
"Crime",
"Thriller"
]
}
]
先計算總共有幾筆資料:db.demo.find().count()
接著檢視一下 document 的格式:db.demo.findOne({})
我們還沒有建立索引,如果想要查詢 2015 年以後的電影,使用以下指令:db.demo.find({year: {$gte: 2015}})
我們可以透過 explain()
檢視 find()
的詳細資料:db.demo.explain().find({year: {$gte: 2015}})
也可以使用 explain("executionStats")
來檢視更詳細的資料:db.demo.explain("executionStats").find({year: {$gte: 2015}})
我們可以觀察其中幾項:
接著來比較一下使用索引後進行查詢的效率。首先,先來創建 Index
createIndex()
來創建 Index:db.demo.createIndex({year: 1})
接著我們再透過 explain("executionStats")
來檢視此執行 find()
操作的詳細資料:db.demo.explain("executionStats").find({year: {$gte: 2015}})
我們依樣來觀察以下三點:
可以發現,在我們創建 Index 後,查詢效率明顯提升。
今天介紹了 MongoDB 中的索引,以及只對單一欄位建立索引的方法。下一篇會來討論使用索引的優點及缺點。