iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 20
0
AI & Data

從入門到精通 MongoDB系列 第 20

Day20: 索引 index(1) - 索引介紹及單一欄位的索引

接下來幾篇我們將介紹 MongoDB 中的一個重要概念:Index 索引。索引的使用會讓我們進行查詢時有很大的影響。


什麼是索引?為什麼要用索引?

在 MongoDB 中我們可以建立索引 Index,讓之後進行查詢時更有效率。如果查詢的欄位是已經有建立 Index 的欄位,MongoDB 就不會進去資料欄位,而是調出己經建好 B-tree 的 Index 來查詢。

使用索引 Index

我們使用以下指令進行查詢:db.collection.find({age: 30}),MongoDB 預設使用 Collection Scan 去掃描整個 collection 來做查詢,但隨著 collection 數量增加,查詢的效率會降低。

而如果我們使用索引 Index,MongoDB 則會對查詢的欄位進行有序排列,且每個 index 都有 pointer 指向原先對應之 document。因此,在查詢時只會進行 Index Scan,進而提升查詢效率。

對每個欄位都建立索引嗎?

在 MongoDB 中,我們可以對每個欄位都建立索引,但會有相對的代價:

  • insert 和 update 的更改成本高

我們可以改成只針對查詢頻率高的欄位去建 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()

  • object 數量為 28795

接著檢視一下 document 的格式:db.demo.findOne({})

沒有使用索引來查詢

我們還沒有建立索引,如果想要查詢 2015 年以後的電影,使用以下指令:db.demo.find({year: {$gte: 2015}})

  • 有 747 部電影

我們可以透過 explain() 檢視 find() 的詳細資料:db.demo.explain().find({year: {$gte: 2015}})

也可以使用 explain("executionStats") 來檢視更詳細的資料:db.demo.explain("executionStats").find({year: {$gte: 2015}})

我們可以觀察其中幾項:

  • "COLLSCAN":使用 Collection Scan 來查詢
  • "executionTimeMillis":執行查詢花了 18 ms
  • "totalDocsExamined": 總共掃描 28795 個文件

使用索引來進行查詢

接著來比較一下使用索引後進行查詢的效率。首先,先來創建 Index

  • 使用 createIndex() 來創建 Index:db.demo.createIndex({year: 1})
    • 1:year 由小到大的順序建立 index
    • "numberIndexBefore":1,預設有一個 index 為 "_id"

接著我們再透過 explain("executionStats") 來檢視此執行 find() 操作的詳細資料:db.demo.explain("executionStats").find({year: {$gte: 2015}})

我們依樣來觀察以下三點:

  • "IXSCAN":Index Scan
  • "executionTimeMillis":查詢執行時間為 11 ms
  • "totalDocsExamined":總共掃描 747 個文件

可以發現,在我們創建 Index 後,查詢效率明顯提升。


今天介紹了 MongoDB 中的索引,以及只對單一欄位建立索引的方法。下一篇會來討論使用索引的優點及缺點。


上一篇
Day19: 進階的 CRUD 操作(9) - upsert 及刪除資料的補充內容
下一篇
Day21: 索引 index(2) - index 的優點與缺點
系列文
從入門到精通 MongoDB26

尚未有邦友留言

立即登入留言