概述
MongoDB是屬于文檔型的NoSQL數據庫,也就是文檔數據庫。文檔數據庫區別于傳統的其它數據庫,它是用來管理文檔。在傳統的數據庫中,信息被分割成離散的數據段,而在文檔數據庫中,文檔是處理信息的基本單位,
一個文檔相當于關系數據庫中的一條記錄。
數據結構
總體的數據結構與關系型數據庫對比表格:
關系型數據庫 | mongodb |
---|---|
database(數據庫) | database(數據庫) |
table(表) | collection(集合) |
row(行) | document(文檔) |
column(列) | field(字段) |
index(索引) | index(索引) |
其中document是bson格式的,例子:
{field1: value1,field2: value2,field3: value3,...fieldN: valueN
}
其數據結構類型表格(參照官網的):
類型 | 數字 | 別名 | 說明(只解釋難理解的) |
---|---|---|---|
Double | 1 | “double” | |
String | 2 | “string” | |
Object | 3 | “object” | 這里的數據結構類型,做內嵌文檔使用。 |
Array | 4 | “array” | |
Binary data | 5 | “binData” | |
Undefined | 6 | “undefined” | Deprecated. |
ObjectId | 7 | “objectId” | 用來創建id的對象,存儲后顯示為ObjectId(“id”) |
Boolean | 8 | “bool” | |
Date | 9 | “date” | |
Null | 10 | “null” | |
Regular Expression | 11 | “regex” | |
DBPointer | 12 | “dbPointer” | Deprecated. |
JavaScript | 13 | “javascript” | |
Symbol | 14 | “symbol” | Deprecated. |
JavaScript (with scope) | 15 | “javascriptWithScope” | |
32-bit integer | 16 | “int” | |
Timestamp | 17 | “timestamp” | |
64-bit integer | 18 | “long” | |
Decimal128 | 19 | “decimal” | New in version 3.4. |
Min key | -1 | “minKey” | |
Max key | 127 | “maxKey” |
存儲引擎
存儲引擎是數據庫的組成部分,負責管理數據在內存和磁盤中的存儲方式。
MongoDB支持多個存儲引擎,因為不同的引擎對于特定的工作負載表現更好。
MMAPv1
3.0版本以前,MongoDB只有一個存儲引擎——MMAP,MongoDB3.0引進了一個新的存儲引擎——WiredTiger,同時對原有的MMAP引擎進行改進,產生MMAPv1存儲引擎,并將其設置為MongoD3.0的默認存儲引擎。然而MMAP引擎的一些弊端在MMAPv1引擎依舊存在,3.2版本開始,MongoDB已將默認的存儲引擎設置為WiredTiger,從MongoDB 4.0起已棄用MMAPv1引擎。
作為MongoDB原生的存儲引擎,MMAPv1也是有它自己的優勢的。MMAPv1基于內存映射文件,它擅長于大容量插入、讀取和就地更新的工作負載。
文件結構
使用MMAPv1存儲引擎,每個數據庫由一個.ns文件和一個或多個數據文件組成,假設數據庫名稱為mydb,則.ns文件名稱為mydb.ns,數據文件名稱為:mydb.0,mydb.1,mydb.2…,文件編號從0開始,文件大小從64MB開始,依次倍增,最大為2GB。
.ns文件實際上是一個hash表,用于快速定位某個集合在數據文件中存儲的起始位置。每個數據文件被劃分成多個extent,每個extent只包含一個集合的數據,同一個集合的所有extent之間使用雙向鏈表連接,一個extent包含多個文檔,同一個extent中的所有文檔也使用雙向鏈表連接,所以,同一個集合中所有文檔是使用雙向鏈表連接的。
.ns文件的數據組織結構如下:
數據文件的數據組織結構如下:
內存使用
為了保證連續的存儲空間,避免產生磁盤碎片,MMAPv1對數據文件的使用采用預分配策略:數據庫創建之后,先創建一個編號為0的文件,大小為64M,當這個文件有一半以上被使用時,再創建一個編號為1的文件,大小是上一個文件的兩倍,即128M,依此類推,直到創建文件大小達到2G,以后再創建的文件大小就都是2G了。
使用MMAPv1存儲引擎,MongoDB會自動使用所有機器的空閑的內存作為它的cache,即MongoDB會使用盡可能多的空閑的內存。但MongoDB使用的內存由系統資源監視器監視,由系統控制,可隨時回收,如果其他的進程突然需要服務器大量的內存,MongoDB將會讓出內存給其他的進程。當然,使用MMAPv1存儲引擎的時候,分配的內存越大,MongoDB的性能就越好。
MMAPv1存儲引擎是在數據庫級別分配文件的,將每個數據庫中所有的集合和索引都混合存儲在數據庫文件中,即使刪除了某個集合或索引,其占用的磁盤空間也很難及時自動回收。
WiredTiger
WiredTiger是在MongoDB3.0版本引入的,并且在MongoDB3.2版本開始成為MongoDB默認的存儲引擎。相比較MMAPv1,WiredTiger功能更強大,而且具有更高的性能。
文件結構
WiredTIger則在集合和索引級別分配文件,將每個數據庫中所有的集合和索引都存儲在單獨的文件中,集合或索引刪除后,其對應文件即可刪除,磁盤空間回收方便。
WiredTiger的一些數據文件:
- mongod.lock:用于防止多個進程連接同一個WiredTiger數據庫
- .wt文件:存儲各個集合的數據,每個文件100MB
- WiredTiger.wt:用于存儲所有集合的元數據信息
- WiredTiger.turtle:用于存儲WiredTiger.wt的元數據信息
- journal文件夾:用于存儲日志文件(Write ahead log)
鎖
WiredTiger存儲引擎使用文檔級別鎖,同一時刻多個寫操作可以修改同一個集合中不同的文檔,但不能修改同一個文檔。
對于大多數讀寫操作,WiredTiger 使用樂觀并發控制。WiredTiger 僅在全局、數據庫和集合級別使用意圖鎖。當存儲引擎檢測到兩個操作之間的沖突時,會引發寫入沖突,導致 MongoDB 透明地重試該操作。
一些全局操作,通常是涉及多個數據庫的短期操作,仍然需要全局“實例范圍”鎖。其他一些操作,例如刪除集合,仍然需要獨占數據庫鎖。
mvcc
WiredTiger 使用多版本并發控制 (MVCC)。在操作開始時,WiredTiger 會為操作提供數據的時間點快照。快照呈現內存中數據的一致視圖。
mvcc會在下面單獨作為一個模塊來講。
內存使用
按照MongoDB默認的配置,WiredTiger的寫操作會先寫入Cache(BTree結構),當Cache大小達到128KB時便將其持久化到預寫日志文件(Write ahead log)。WiredTiger每60s或日志文件大小達到2GB時會做一次檢查點Checkpoint,產生指定時間點的數據庫快照(內存中數據的一致性視圖),將快照中的所有數據以一致性方式持久化到數據文件中,保證數據文件和內存數據是一致的。Wiredtiger連接初始化時,首先將數據恢復至最新的快照狀態,然后根據預寫日志文件恢復數據,以保證存儲可靠性。
使用WiredTiger存儲引擎時,MongoDB數據緩存分兩部分:內部緩存和文件系統緩存。內部緩存大小可以使用–wiredTigerCacheSizeGB參數來設置,默認值為:256MB或(RAM - 1 GB) 的 50%之間,取兩值中較大者。文件系統緩存大小則不固定,MongoDB自動使用系統空閑的內存,且數據在文件系統緩存中是壓縮存儲的。
使用 WiredTiger存儲引擎時,MongoDB 支持所有集合和索引的壓縮。壓縮以增加 CPU 為代價最大限度地減少了存儲使用。
默認情況下,WiredTiger 對所有集合使用 Snappy 塊壓縮,對所有索引使用前綴壓縮。壓縮默認值可在全局級別配置,也可以在集合和索引創建期間基于每個集合和每個索引進行設置。
對于集合,還可以使用以下塊壓縮庫:
- zlib
- zstd(從 MongoDB 4.2 開始可用)
In-Memory
In-Memory存儲引擎將數據庫數據都存儲在內存中,只將少量的元數據和診斷日志、臨時數據存儲到硬盤文件中,避免了磁盤I/O操作,查詢速度很快。
鎖
In-Memory存儲引擎使用文檔級別鎖,同一時刻多個寫操作可以修改同一個集合中不同的文檔,但不能修改同一個文檔。
內存使用
In-Memory需要將數據庫的數據、索引和操作日志等內容存儲到內存中。可以通過參數–inMemorySizeGB設置它占用的內存大小,默認為:(RAM - 1 GB) 的 50%。
In-Memory不需要單獨的日志文件,不存在記錄日志和等待數據持久化的問題。當MongoDB實例關機或系統異常終止時,所有存儲在內存中的數據都將會丟失。
In-Memory雖然不將數據寫入硬盤,但還是會記錄oplog。利用這個特性,可以在集群中使用In-Memory的MongoDB作為主數據庫,使用WiredTiger的MongoDB作為備份數據庫,然后將主數據庫的oplog推送給備份數據庫進行持久化存儲,這樣即使主數據庫關機或異常崩潰,重啟后還可以從備份數據庫中同步數據。
索引
索引是加快查詢的手段,MongoDB的索引支持選擇正序、倒序創建,值1指定按升序排列項目的索引。的值-1指定按降序排列項目的索引。
應用程序在索引構建期間可能會遇到性能下降,包括對集合的讀/寫訪問。
類型
單鍵索引
單鍵索引(Single Field)顧名思義就是單個字段作為索引列,MongoDB的所有collection默認都有一個單鍵索引_id。
復合索引
單鍵索引(Single Field)顧名思義就是多個字段組合作為索引列,使用復合索引時要注意字段的順序,如下添加一個name和age的復合索引,name正序,age倒序,document首先按照name正序排序,然后name相同的document按age進行倒序排序。mongoDB中一個復合索引最多可以包含32個字段。
多鍵索引
多鍵索引(MutiKey)是建在數組上的索引,可指定某個數組字段下的字段。
文本索引
文本索引(Text)來支持對字符串內容的文本搜索查詢。 文本索引可以包括其值為字符串或字符串元素數組的任何字段。一個集合只能有一個文本搜索索引,但該索引可以覆蓋多個字段。
權重
對于文本索引,索引字段的權重表示該字段相對于其他索引字段在文本搜索分數方面的重要性。
對于文檔中的每個索引字段,MongoDB 將匹配數乘以權重并將結果相加。使用這個總和,MongoDB 然后計算文檔的分數。
索引字段的默認權重為 1。
通配符索引
通配符索引(Wildcard)是在一個字段或一組字段上創建索引以支持查詢。由于 MongoDB 支持動態模式,因此應用程序可以查詢名稱無法提前知道或任意的字段。
二維球體索引
二維球體索引(2dsphere)支持計算類地球體上的幾何形狀的查詢, 它支持所有 MongoDB 地理空間查詢:包含、交叉和鄰近查詢。
二維索引
二維索引(2d)對存儲為二維平面上的點的數據使用索引。該2d索引適用于 MongoDB 2.2 及更早版本中使用的舊坐標對。
在以下情況下使用2d索引:
- 數據庫具有來自 MongoDB 2.2 或更早版本的舊版坐標對,并且不打算將任何位置數據存儲為GeoJSON對象。
哈希索引
哈希索引(Hashed)就是將field的值進行hash計算后作為索引,其強大之處在于實現O(1)查找,當然用哈希索引最主要的功能也就是實現定值查找,對于經常需要排序或查詢范圍查詢的集合不要使用哈希索引。
MongoDB 不支持對哈希索引指定唯一約束。您可以改為創建一個附加的非散列索引,該索引具有對該字段的唯一約束。MongoDB 可以使用該非散列索引來強制該字段的唯一性。
屬性
TTL 索引
TTL 索引是特殊的單字段索引,MongoDB 可以使用它在一定時間或特定時鐘時間后自動從集合中刪除文檔。數據過期對于某些類型的信息很有用,例如機器生成的事件數據、日志和會話信息,這些信息只需要在數據庫中保留有限的時間。
TTL 索引不保證過期數據會在過期后立即被刪除,文檔過期和 MongoDB 從數據庫中刪除文檔的時間之間可能存在延遲。
刪除過期文檔的后臺任務每 60 秒運行一次,因此,在文檔到期和后臺任務運行之間的時間段內,文檔可能會保留在集合中。
由于刪除操作的持續時間取決于數據庫實例的工作負載,因此在后臺任務運行之間的 60 秒時間段之后mongod,過期數據可能會存在一段時間。
使用限制:
- TTL 索引是單字段索引。復合索引不支持 TTL 并忽略該 expireAfterSeconds選項。
- 該_id字段不支持 TTL 索引。
- 無法在上限集合上創建 TTL 索引,因為 MongoDB 無法從上限集合中刪除文檔。
- 不能在時間序列集合上創建 TTL 索引。類似的功能是通過自動刪除時間序列集合來提供的。
- 不能用于createIndex()更改expireAfterSeconds現有索引的值。而是將 collMod數據庫命令與 index收集標志結合使用。否則,要更改現有索引的選項值,必須先刪除索引并重新創建。
- 如果某個字段已經存在非 TTL 單字段索引,則無法在同一字段上創建 TTL 索引,因為您無法創建具有相同鍵規范且僅選項不同的索引。要將非 TTL 單字段索引更改為 TTL 索引,必須先刪除索引并使用該 expireAfterSeconds選項重新創建。
唯一索引
唯一索引(Unique)確保索引字段不存儲重復值,即強制索引字段的唯一性。默認情況下,MongoDB 在創建集合期間會在_id字段上創建唯一索引。
如果文檔在唯一索引中沒有索引字段的值,則索引將為此文檔存儲空值。由于唯一性約束,MongoDB 將只允許一個缺少索引字段的文檔。如果有多個文檔沒有索引字段的值或缺少索引字段,則索引構建將失敗并出現重復鍵錯誤。
稀疏索引
稀疏索引(Sparse)僅包含具有索引字段的文檔的條目,即使索引字段包含空值。索引會跳過任何缺少索引字段的文檔。索引是“稀疏的”,因為它不包括集合的所有文檔。相比之下,非稀疏索引包含集合中的所有文檔,為那些不包含索引字段的文檔存儲空值。
從 MongoDB 3.2 開始,MongoDB 提供了創建 部分索引的選項。部分索引提供了稀疏索引功能的超集。如果您使用的是 MongoDB 3.2 或更高版本,則應優先使用部分索引而不是稀疏索引。
部分索引
部分索引(Partial)僅索引集合中滿足指定過濾器表達式的文檔。通過對集合中的文檔子集進行索引,部分索引具有較低的存儲要求并降低了索引創建和維護的性能成本。
舉個例子,以下操作創建一個復合索引,該索引僅索引rating字段大于 5 的文檔:
db.restaurants.createIndex({ cuisine: 1, name: 1 },{ partialFilterExpression: { rating: { $gt: 5 } } }
)
不區分大小寫的索引
不區分大小寫的索引(Case Insensitive)支持執行字符串比較而不考慮大小寫的查詢。
隱藏索引
隱藏索引(Hidden)對查詢計劃程序不可見,并且不能用于支持查詢。
通過對規劃器隱藏索引,用戶可以在不實際刪除索引的情況下評估刪除索引的潛在影響。如果影響是負面的,用戶可以取消隱藏索引,而不必重新創建已刪除的索引。
集群
由于單機垂直擴展能力的局限,水平擴展的方式則顯得更加的靠譜。 MongoDB 自帶了這種能力,可以將數據存儲到多個機器上以提供更大的容量和負載能力。
此外,同時為了保證數據的高可用,MongoDB 采用副本集的方式來實現數據復制。
一個典型的MongoDB集群架構會同時采用分片+副本集的方式,如下圖:
主從復制
主從復制是 MongoDB 最早使用的復制方式, 該復制方式易于配置,并且可以支持任意數量的從節點服務器,與使用單節點模式相比有如下優點:
- 在從服務器上存儲數據副本,提高了數據的可用性, 并可以保證數據的安全性。
- 可配置讀寫分離,主節點負責寫操作,從節點負責讀操作,將讀寫壓力分開,提高系統的穩定性。
MongoDB 的主從復制至少需要兩個服務器或者節點。其中一個是主節點,負責處理客戶端請求,其它的都是從節點,負責同步主節點的數據。
主節點記錄在其上執行的所有寫操作,從節點定期輪詢主節點獲取這些操作,然后再對自己的數據副本執行這些操作。由于和主節點執行了相同的操作,從節點就能保持與主節點的數據同步。
主節點的操作記錄稱為oplog(operation log),它被存儲在 MongoDB 的 local 數據庫中。oplog 中的每個文檔都代表主節點上執行的一個操作。需要重點強調的是oplog只記錄改變數據庫狀態的操作。比如,查詢操作就不會被存儲在oplog中。這是因為oplog只是作為從節點與主節點保持數據同步的機制。
然而,主從復制并非生產環境下推薦的復制方式,主要原因如下兩點:
- 災備都是完全人工的 如果主節點發生故障失敗,管理員必須關閉一個從服務器,然后作為主節點重新啟動它。然后應用程序必須重新配置連接新的主節點。
- 數據恢復困難 因為oplog只在主節點存在,故障失敗需要在新的服務器上創建新的oplog,這意味著任意存在的節點需要重新從新的主節點同步oplog。
因此,在新版本的MongoDB中已經不再支持使用主從復制這種復制方式了,取而代之的是使用副本集復制方式。
副本集
MongoDB副本集(Replica Set)其實就是具有自動故障恢復功能的主從集群,和主從復制最大的區別就是在副本集中沒有固定的“主節點;整個副本集會選出一個節點作為“主節點”,當其掛掉后,再在剩下的從節點中選舉一個節點成為新的“主節點”,在副本集中總有一個主節點(primary)和一個或多個備份節點(secondary)。
官方推薦的副本集最小配置需要有三個節點:一個主節點接收和處理所有的寫操作,兩個備份節點通過復制主節點的操作來對主節點的數據進行同步備份。
成員
成員 | 說明 |
---|---|
Secondary | 正常情況下,復制集的Seconary會參與Primary選舉(自身也可能會被選為Primary),并從Primary同步最新寫入的數據,以保證與Primary存儲相同的數據。 |
Secondary可以提供讀服務,增加Secondary節點可以提供復制集的讀服務能力,同時提升復制集的可用性。另外,Mongodb支持對復制集的Secondary節點進行靈活的配置,以適應多種場景的需求。 | |
Arbiter | Arbiter節點只參與投票,不能被選為Primary,并且不從Primary同步數據。 |
比如你部署了一個2個節點的復制集,1個Primary,1個Secondary,任意節點宕機,復制集將不能提供服務了(無法選出Primary),這時可以給復制集添加一個Arbiter節點,即使有節點宕機,仍能選出Primary。
Arbiter本身不存儲數據,是非常輕量級的服務,當復制集成員為偶數時,最好加入一個Arbiter節點,以提升復制集可用性。 |
| Priority0 | Priority0節點的選舉優先級為0,不會被選舉為Primary
比如你跨機房A、B部署了一個復制集,并且想指定Primary必須在A機房,這時可以將B機房的復制集成員Priority設置為0,這樣Primary就一定會是A機房的成員。
(注意:如果這樣部署,最好將『大多數』節點部署在A機房,否則網絡分區時可能無法選出Primary) |
| Vote0 | Mongodb 3.0里,復制集成員最多50個,參與Primary選舉投票的成員最多7個,其他成員(Vote0)的vote屬性必須設置為0,即不參與投票。 |
| Hidden | Hidden節點不能被選為主(Priority為0),并且對Driver不可見。因Hidden節點不會接受Driver的請求,可使用Hidden節點做一些數據備份、離線計算的任務,不會影響復制集的服務。 |
| Delayed | Delayed節點必須是Hidden節點,并且其數據落后與Primary一段時間(可配置,比如1個小時)。
因Delayed節點的數據比Primary落后一段時間,當錯誤或者無效的數據寫入Primary時,可通過Delayed節點的數據來恢復到之前的時間點。 |
選舉
副本集通過replSetInitiate命令(或mongo shell的rs.initiate())進行初始化,初始化后各個成員間開始發送心跳消息,并發起Priamry選舉操作,獲得『大多數』成員投票支持的節點,會成為Primary,其余節點成為Secondary。
假設復制集內投票成員數量為N,當副本集內存活成員數量不足N/2 + 1時,整個復制集將無法選舉出Primary,復制集將無法提供寫服務,處于只讀狀態,通常建議將副本集成員數量設置為奇數。
仲裁者
在某些情況下(例如,當有主服務器和輔助服務器,但成本限制禁止添加另一個輔助服務器時),我們可以選擇將仲裁器添加到副本集。
仲裁器參與主節點的選舉,但仲裁器沒有數據集的副本,不能成為主節點。
仲裁者擁有準確的1選舉投票。默認情況下,仲裁者具有優先權0。
例如,在以下具有 2 個數據承載成員(主要和次要)的副本集中,仲裁器允許該集合擁有奇數票數來打破平局:
oplog
oplog是local庫下的一個固定集合,Secondary就是通過查看Primary 的oplog這個集合來進行復制的。每個節點都有oplog,記錄這從主節點復制過來的信息,這樣每個成員都可以作為同步源給其他節點。
oplog 可以說是Mongodb Replication的紐帶了。
當第一次啟動一個副本集成員時,如果不指定 oplog 大小,MongoDB 會創建一個基于操作系統的默認大小的 oplog。
在創建 oplog 之前,可以使用oplogSizeMB選項指定其大小。
首次啟動副本集成員后,使用replSetResizeOplog管理命令更改 oplog 大小,使其能夠在不重新啟動進程replSetResizeOplog的情況下動態調整 oplog 的大小。
下面,看看一條 oplog 的具體形式:
{
"ts" : Timestamp(1446011584, 2),
"h" : NumberLong("1687359108795812092"),
"v" : 2,
"op" : "i",
"ns" : "test.nosql",
"o" : { "_id" : ObjectId("563062c0b085733f34ab4129"), "name" : "mongodb", "score" : "100" }
}
其中的一些關鍵字段有:
- ts 操作的 optime,該字段不僅僅包含了操作的時間戳(timestamp),還包含一個自增的計數器值。
- h 操作的全局唯一表示
- v oplog 的版本信息
- op 操作類型,比如 i=insert,u=update…
- ns 操作集合,形式為 database.collection
- o 指具體的操作內容,對于一個 insert 操作,則包含了整個文檔的內容
心跳
在高可用的實現機制中,心跳(heartbeat)是非常關鍵的,判斷一個節點是否宕機就取決于這個節點的心跳是否還是正常的。
副本集中的每個節點上都會定時向其他節點發送心跳,以此來感知其他節點的變化,比如是否失效、或者角色發生了變化。
默認情況下,節點會每2秒向其他節點發出心跳,這其中包括了主節點。 如果備節點在10秒內沒有收到主節點的響應就會主動發起選舉。
此時新一輪選舉開始,新的主節點會產生并接管原來主節點的業務。 整個過程對于上層是透明的,應用并不需要感知,因為 Mongos 會自動發現這些變化。
如果應用僅僅使用了單個副本集,那么就會由 Driver 層來自動完成處理。
分片
高數據量和吞吐量的數據庫應用會對單機的性能造成較大壓力,大的查詢量會將單機的CPU耗盡,大的數據量對單機的存儲壓力較大,最終會耗盡系統的內存而將壓力轉移到磁盤IO上。
為了解決這些問題,有兩個基本的方法: 垂直擴展和水平擴展。
- 垂直擴展:增加更多的CPU和存儲資源來擴展容量。
- 水平擴展:將數據集分布在多個服務器上。水平擴展即分片。
分片架構
組件 | 說明 |
---|---|
Config Server | 存儲集群所有節點、分片數據路由信息。默認需要配置3個Config Server節點。 |
Mongos | 提供對外應用訪問,所有操作均通過mongos執行。一般有多個mongos節點。數據遷移和數據自動平衡。 |
Mongod | 存儲應用數據記錄。一般有多個Mongod節點,達到數據分片目的。 |
- Mongos :數據路由,和客戶端打交道的模塊。mongos本身沒有任何數據,他也不知道該怎么處理這數據,去找config server。
- Config Server:所有存、取數據的方式,所有shard節點的信息,分片功能的一些配置信息。可以理解為真實數據的元數據。
- Shard:真正的數據存儲位置,以chunk為單位存數據。
分片機制
首先,基于分片切分后的數據塊稱為 chunk,一個分片后的集合會包含多個 chunk,每個 chunk 位于哪個分片(Shard) 則記錄在 Config Server(配置服務器)上。
Mongos 在操作分片集合時,會自動根據分片鍵找到對應的 chunk,并向該 chunk 所在的分片發起操作請求。
數據是根據分片策略來進行切分的,而分片策略則由 分片鍵(ShardKey)+分片算法(ShardStrategy)組成。
調優
explain
使用 explain() 命令可以用于查詢計劃分析,進一步評估索引的效果,詳細說明可參考官網。
如下:
db.test.explain().find( { a : 5 } ){"queryPlanner" : {..."winningPlan" : {"stage" : "FETCH","inputStage" : {"stage" : "IXSCAN","keyPattern" : {"a" : 5},"indexName" : "a_1","isMultiKey" : false,"direction" : "forward","indexBounds" : {"a" : ["[5.0, 5.0]"]}}}},...
}
---------------------
作者:我叫小八
來源:CSDN
原文:https://blog.csdn.net/h295928126/article/details/123833636
版權聲明:本文為作者原創文章,轉載請附上博文鏈接!
內容解析By:CSDN,CNBLOG博客文章一鍵轉載插件