【資料庫寶典】 MongoDB - 進階索引

更新於 發佈於 閱讀時間約 12 分鐘

MongoDB - 索引類型

本篇主要是介紹MongoDB有哪些進階的索引, 了解原理及功能後, 在應用上才能規劃出更有效率的索引, 而主要會談到以下五個索引類型:
  • 複合索引。
  • 部份索引。
  • 多鍵索引。
  • 全文索引。
  • TTL索引。
進入到索引類型之前先提醒一下,一個集合的索引數不能超過64個。

複合索引

限制: 最多只能31個欄位做一組複合索引。
建立方式:
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )
// 補充: <type>就是1或-1,代表正序或倒序。
首先我們實際來建立一組索引,叫做「人員分數查詢」專用的索引。
db.collection.createIndex({ userid: 1, score: -1}, {name: "人員分數查詢專用索引"})
接著建立幾個樣本資料:
[
{
"userid": "aa1",
"score": 45
},
{
"userid": "ca2",
"score": 55
},
{
"userid": "ca2",
"score": 75
},
{
"userid": "ca2",
"score": 30
},
{
"userid": "nb1",
"score": 30
},
{
"userid": "xyz",
"score": 90
}
]

案例一: 查詢條件發揮複合索引效用。

接著我們來做個查詢分析,分析我們的條件是否在索引之下發揮最大效用。
db.getCollection('test').find({"userid": "ca2", "score": 30}).explain("executionStats")
我們可以發現到Mongo選出來的最佳查詢計畫stage是FETCH,這個我們可以理解為透過索引直接找到文本,而inputStage代表著我們先針對userid, score這兩個索引做掃描,關於查詢分析這邊先不探討,會另外開一篇專門介紹。
  • COLLSCAN:全表掃描。
  • IXSCAN:索引掃描。
  • FETCH: 根據索引到指定的document。
上述結果成功發揮索引效用。

案例二: 查詢條件未能發揮效用

假設今天只找分數不找人員
db.getCollection('test').find({"score": 30}).explain("executionStats")
我們可以發現到Mongo分析出來的查詢計畫是全局掃描,也就是未能發揮索引效用,因此索引建立的順序是有意義的,需要根據需求來進行索引設計。
適用場景: 查詢欄位不只一個,且複合索引的欄位符合建立索引的順序,才能發揮最大的效用*。*

部分索引

我們不想針對該欄位全部的value都進行索引,就可以使用這種索引方式,舉例來說,我們只想對age > 25的值進行索引,建立方式如下:
db.persons.createIndex({country:1},{partialFilterExpression: {age: {$gt:25}}})
  • 其實就是帶有過濾條件的索引,大數據的應用確實應該分析及規劃這個部分。
  • 滿足查詢條件在查詢時才能發揮索引效用,假設我們條件改為age >= 25,那麼Mongo的查詢計畫就會給出全局掃描的選項。

多鍵索引

其實就是對嵌套的文檔做索引。

全文索引

  • 目前不支援中文。
  • 會以空白隔開的方式來建立索引。
{
"id": "1",
"post_text": "enjoy the mongodb articles on Runoob",
}db.posts.ensureIndex({post_text:"text"})# 索引示意: 會以term做為索引的key來記載出現的位置...。
# enjoy => [1, 2...]
# the => [1...]
# ...
  • 搜尋也是有一些強大功能的, 如下:
// 簡單的查詢mongodb這個詞。
db.posts.find( { $text: { $search: "mongodb" } } );
// 查詢mongodb或articles這兩個詞。
db.posts.find({$text:{$search:"mongodb articles"}});
// 查詢包含mongodb但不包含elasticsearch的文本, 會用`-`來表示不包含。
db.posts.find({$text:{$search:"mongodb -elasticsearch"}});
// 查詢「mongodb articles」這個片語的文本。
db.posts.find({$text:{$search:"\\"mongodb articles\\""}})

TTL索引

TTL索引常常用在log應用, 假設使用者操作的歷程我們只想要保留半年, 則我們可以針對Collection進行TTL索引的建立, 而Mongo背景服務就會定時幫我們清除過期的資料, 但是使用上有幾個特別要注意的地方如下:

清除的型態是什麼?

  • 只能是BSON的Date型態才能被清除。
  • 如果用整數的Timestamp會沒有作用。

如果Collection本身已經是Capped的話, 我們又設定TTL會發生什麼事情呢?

會發生以下的錯誤訊息, 由於我們基礎篇有提到Capped Collection如果要刪除Document只能對整個Collection進行刪除, 故我們如果需求上已經對某個Collection規劃為Capped時, 就不要在用TTL索引了!!!
2020-11-23T03:36:21.405+0000 E INDEX    [TTLMonitor] Error processing ttl index: { v: 2, key: { creationTime: 1 }, name: "expiredIdx", ns: "qa.qm_event_log", expireAfterSeconds: 1, background: true } -- 10089 cannot remove from a capped collection

如何更新TTL失效時間?

  • 已建立的索引, 如果動態更改TTL參數會發生錯誤如下。
db.createIndex(...)
Index with name: expiredIdx already exists with different options
  • 使用DB Command「collMod」來更新。
// Update the index with 120 seconds expiration threshold
db.runCommand({
collMod: 'ttldemo',
index: {keyPattern: {created_at: 1}, expireAfterSeconds: 120}
});
  • 刪除重建。

刪除重建後,之前的Documents會套用嗎?

  • 我們先預設一小時後失效。
db.test.createIndex({created_at: 1}, {expireAfterSeconds: 600});
  • 建立一筆Document時間為now。
db.test.insert({
created_at: new Date()
})
  • 此時我們先確保背景服務不會去刪除我們的Document
2020-11-23T04:22:21.437+0000 D INDEX    [TTLMonitor] ns: qa.test key: { created_at: 1.0 } name: created_at_1
2020-11-23T04:22:21.437+0000 D INDEX [TTLMonitor] deleted: 0
  • 刪除重建索引為1秒鐘後失效。
db.test.dropIndex("created_at_1");
db.test.createIndex({created_at: 1}, {expireAfterSeconds: 1});
  • 再建立一筆Document時間為now。
db.test.insert({
created_at: new Date()
})
  • 此時已有兩筆, 我們來看看是否兩筆都會套用? 答案是會的!
2020-11-23T04:25:21.439+0000 D INDEX    [TTLMonitor] ns: qa.test key: { created_at: 1.0 } name: created_at_1
2020-11-23T04:25:21.439+0000 D INDEX [TTLMonitor] deleted: 2

如何監控TTL是否執行?

預設的MongoDB不會將TTL訊息印出, 如果我們打算讓該Log訊息印出, 則可以透過以下的配置來完成。
db.setLogLevel(1, "index");
印出訊息如下, Log會告知我們哪個時間點清除了哪些資料:
2020-11-23T03:40:21.407+0000 D INDEX    [TTLMonitor] ns: admin.logsfilter key: { expiredAt: 1 } name: expiredAt_1
2020-11-23T03:40:21.407+0000 D INDEX [TTLMonitor] deleted: 0
2020-11-23T03:40:21.407+0000 D INDEX [TTLMonitor] ns: qa.error_log key: { creationTime: 1 } name: expiredIdx
2020-11-23T03:40:21.407+0000 D INDEX [TTLMonitor] deleted: 0

MongoDB背景多久執行一次TTL清除動作?

  • 預設60秒執行一次清除動作。
db.adminCommand({getParameter:1, ttlMonitorSleepSecs: 1});{
"ttlMonitorSleepSecs" : 60,
"ok" : 1.0
}
  • 如何更改執行間隔(盡量不要太短, TTL索引過多將造成CPU負荷)。
> db.adminCommand({setParameter:1, ttlMonitorSleepSecs: 3600}); // 1 minute
{ "was" : 60, "ok" : 1 }

TTL刪除了多少Document

db.serverStatus().metrics.ttl
{
"deletedDocuments" : NumberLong(13533),
"passes" : NumberLong(20374)
}

常用的指令

# 查看collection佔用索引的容量
db.collection.totalIndexSize()
為什麼會看到廣告
avatar-img
118會員
266內容數
哈囉,我是阿Han,是一位 👩‍💻 軟體研發工程師,喜歡閱讀、學習、撰寫文章及教學,擅長以圖代文,化繁為簡,除了幫助自己釐清思路之外,也希望藉由圖解的方式幫助大家共同學習,甚至手把手帶您設計出高品質的軟體產品。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
阿Han的沙龍 的其他內容
主要是收攏documents的容器, 可以支援各種不同結構的document。 不能為空字串。 不能以system開頭, 這是系統集合保留的前綴。 超過配置大小, 新增時當超過配置限額時, 會先從最早的document刪除後再append新的document。 更新時不能超過size限制。 不能刪除
大數據的時代,如何有效率的搜尋來找到我們要的答案?這時候就要透過一些資訊檢索的技術來幫我們提升效率了,而本篇會介紹索引的基本概念以及為什麼演化至倒排索引,為我們帶來了哪些好處? 什麼是索引? 那什麼又是倒排索引? 能解決什麼問題呢? 為什麼更快更精準? 結語
主要是收攏documents的容器, 可以支援各種不同結構的document。 不能為空字串。 不能以system開頭, 這是系統集合保留的前綴。 超過配置大小, 新增時當超過配置限額時, 會先從最早的document刪除後再append新的document。 更新時不能超過size限制。 不能刪除
大數據的時代,如何有效率的搜尋來找到我們要的答案?這時候就要透過一些資訊檢索的技術來幫我們提升效率了,而本篇會介紹索引的基本概念以及為什麼演化至倒排索引,為我們帶來了哪些好處? 什麼是索引? 那什麼又是倒排索引? 能解決什麼問題呢? 為什麼更快更精準? 結語
你可能也想看
Google News 追蹤
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本文介紹了資料庫索引的基本原理、類型以及其在資料查詢中的重要性。索引類似於書的目錄,不僅可以提高查詢效率,還有助於組織資料。文章詳細說明瞭主索引、密集索引、稀疏索引、叢索引和非叢索引的定義與特點,並提供了實際的比喻和例子。透過深入瞭解索引的運作,讀者可以更好地設計和優化資料庫,並提升查詢效能。
Thumbnail
本文探討資料庫中的索引及其關鍵概念,涵蓋何謂索引、其類型與設立原因、索引失效情況及 B-tree 與 B+ tree 的差異,並簡要區分主鍵與外鍵的功能。瞭解索引的運作有助於提升資料查詢效率,並正確選擇適當的索引策略,以確保資料庫的高效運行。
「用一本沒有索引的書會很痛苦。」 「第一個網頁,其實就是內容索引。」 「當你用Google 搜尋,你並不是在搜尋網路,你是在搜尋Google對網路的索引。」 「索引是一個關於時間與知識之間關係的故事。 一方面你想快速查到你想要的資訊, 另一方面你想要知識能像是一塊一塊隨
Thumbnail
這篇文章主要是介紹了SQL查詢效能調校的方法,針對索引最佳化做了整理和分享,並提供了一些注意事項和建議。
Thumbnail
高效生活,幫助你找回更多自己的時間 歡迎來到 AL 的 Googlesheet 學習筆記系列文章。在這個系列中,我們將一步步介紹各種函數,並將它們應用於日常生活中,加速工作、提高效率。 今天要介紹的是使用 Index 、 Counta 函數尋找最後一列的資料!
Thumbnail
這篇文章,會帶著大家複習以前學過的二分搜尋法(Binary Search)框架, 並且以二分搜尋法的概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個實用的演算法框架。 Binary search 二分搜尋法框架 用途: 在已經排序好的數列中尋找目標值。
Thumbnail
題目敘述 題目會給定兩個輸入。 第一個輸入是關鍵字清單products,第二個是使用者輸入的字串searchWord。 要求我們實現關鍵字搜尋建議系統,使用者每輸入一個字元就推薦一次。 推薦時,優先返回字典序(Lecial order)最接近的關鍵字,最多不要超過三個關鍵字。 題目的原文
※ 什麼是MongoDB? MongoDB是一個開源、跨平台的非關聯式資料庫,屬於一種文件導向(Document-oriented database)的資料庫管理系統,也就是 NoSQL 數據庫管理系統(DBMS)。 ※ 什麼是非關聯式資料庫(NoSQL)? 非關聯式資料庫(NoSQL)的意思
Thumbnail
※ 基本操作:SQL 語法,SELECT, WHERE, CREATE, UPDATE, DELETE。 SELECT:從資料庫中或資料表中指定要選擇的欄位中取得資料,稱之為查詢 (query)。 ※ 語法:要由兩部分構成,第一部分是要 "拿什麼" 資料 (若有多項用逗號隔開);第二部分則為
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本文介紹了資料庫索引的基本原理、類型以及其在資料查詢中的重要性。索引類似於書的目錄,不僅可以提高查詢效率,還有助於組織資料。文章詳細說明瞭主索引、密集索引、稀疏索引、叢索引和非叢索引的定義與特點,並提供了實際的比喻和例子。透過深入瞭解索引的運作,讀者可以更好地設計和優化資料庫,並提升查詢效能。
Thumbnail
本文探討資料庫中的索引及其關鍵概念,涵蓋何謂索引、其類型與設立原因、索引失效情況及 B-tree 與 B+ tree 的差異,並簡要區分主鍵與外鍵的功能。瞭解索引的運作有助於提升資料查詢效率,並正確選擇適當的索引策略,以確保資料庫的高效運行。
「用一本沒有索引的書會很痛苦。」 「第一個網頁,其實就是內容索引。」 「當你用Google 搜尋,你並不是在搜尋網路,你是在搜尋Google對網路的索引。」 「索引是一個關於時間與知識之間關係的故事。 一方面你想快速查到你想要的資訊, 另一方面你想要知識能像是一塊一塊隨
Thumbnail
這篇文章主要是介紹了SQL查詢效能調校的方法,針對索引最佳化做了整理和分享,並提供了一些注意事項和建議。
Thumbnail
高效生活,幫助你找回更多自己的時間 歡迎來到 AL 的 Googlesheet 學習筆記系列文章。在這個系列中,我們將一步步介紹各種函數,並將它們應用於日常生活中,加速工作、提高效率。 今天要介紹的是使用 Index 、 Counta 函數尋找最後一列的資料!
Thumbnail
這篇文章,會帶著大家複習以前學過的二分搜尋法(Binary Search)框架, 並且以二分搜尋法的概念為核心, 貫穿一些相關聯的題目,透過框架複現來幫助讀者理解這個實用的演算法框架。 Binary search 二分搜尋法框架 用途: 在已經排序好的數列中尋找目標值。
Thumbnail
題目敘述 題目會給定兩個輸入。 第一個輸入是關鍵字清單products,第二個是使用者輸入的字串searchWord。 要求我們實現關鍵字搜尋建議系統,使用者每輸入一個字元就推薦一次。 推薦時,優先返回字典序(Lecial order)最接近的關鍵字,最多不要超過三個關鍵字。 題目的原文
※ 什麼是MongoDB? MongoDB是一個開源、跨平台的非關聯式資料庫,屬於一種文件導向(Document-oriented database)的資料庫管理系統,也就是 NoSQL 數據庫管理系統(DBMS)。 ※ 什麼是非關聯式資料庫(NoSQL)? 非關聯式資料庫(NoSQL)的意思
Thumbnail
※ 基本操作:SQL 語法,SELECT, WHERE, CREATE, UPDATE, DELETE。 SELECT:從資料庫中或資料表中指定要選擇的欄位中取得資料,稱之為查詢 (query)。 ※ 語法:要由兩部分構成,第一部分是要 "拿什麼" 資料 (若有多項用逗號隔開);第二部分則為