目錄
1、索引數據結構:B-樹
2、索引類型
2.1?單字段索引
2.2?復合索引(最重要!)
2.3?多鍵索引(數組字段)
2.4?地理空間索引
2.5?全文索引
2.6?哈希索引(分片專用)
2.7?TTL 索引(自動過期)
3、索引管理操作
3.1?創建索引
3.2?查看索引
3.3?刪除索引
3.4?修改索引(隱藏/重建)
4、explain分析執行計劃
5、慢查詢分析
5.1 開啟慢查詢記錄
5.2 慢查詢日志分析
1、索引數據結構:B-樹
MongoDB使用B-樹,所有節點都有Data域,只要找到指定索引就可以進?訪問,單次查詢從結構上來看要快于MySql。
2、索引類型
2.1?單字段索引
// 創建:在 age 字段升序索引
db.users.createIndex({ age: 1 })
-
適用:等值查詢、范圍掃描(
age: 25
?或?age: { $gt: 30 }
)
2.2?復合索引(最重要!)
// 創建:先按 city 排序,再按 age 排序
db.users.createIndex({ city: 1, age: -1 })
-
最左前綴原則:
? 有效查詢:{ city: "北京" }
、{ city: "上海", age: { $lt: 30 } }
? 無效查詢:{ age: 25 }
(無法命中索引)
2.3?多鍵索引(數組字段)
// tags 是數組字段:["sports", "music"]
db.products.createIndex({ tags: 1 })
-
行為:為數組中的?每個元素?創建獨立索引項
-
限制:復合索引中?最多一個數組字段
2.4?地理空間索引
// 2dsphere 索引(地球球面坐標)
db.places.createIndex({ loc: "2dsphere" })
查詢示例:
db.places.find({loc: {$near: {$geometry: { type: "Point", coordinates: [116.4, 39.9] },$maxDistance: 1000 // 1公里內}}
})
2.5?全文索引
db.articles.createIndex({ content: "text" })
-
支持:多語言分詞、停用詞過濾
-
搜索:
db.articles.find({ $text: { $search: "mongodb tutorial" } })
2.6?哈希索引(分片專用)
db.users.createIndex({ _id: "hashed" }) // 分片鍵均勻分布
2.7?TTL 索引(自動過期)
// 文檔在 create_time 后 3600 秒自動刪除
db.logs.createIndex({ create_time: 1 }, { expireAfterSeconds: 3600 })
3、索引管理操作
3.1?創建索引
// 后臺構建(不阻塞讀寫)
db.orders.createIndex({ product_id: 1 }, { background: true })
3.2?查看索引
db.collection.getIndexes()
// 輸出:
[{ "v": 2, "key": { "_id": 1 }, "name": "_id_" },{ "v": 2, "key": { "city": 1, "age": -1 }, "name": "city_1_age_-1" }
]
3.3?刪除索引
db.users.dropIndex("city_1_age_-1")
3.4?修改索引(隱藏/重建)
// 隱藏索引(測試性能影響)
db.coll.hideIndex("index_name")
// 重建索引(碎片整理)
db.coll.reIndex()
4、explain
分析執行計劃
db.orders.find({ user_id: 100 }).explain("executionStats")
注意:索引不是免費的?— 每個索引增加 10-20% 的寫入開銷。
explain()接收不同的參數,通過設置不同參數我們可以查看更詳細的查詢計劃。
- queryPlanner:queryPlanner是默認參數,具體執行計劃信息參考下面的表格。
- executionStats:executionStats會返回執行計劃的一些統計信息(有些版本中和allPlansExecution等同)。
- allPlansExecution:allPlansExecution用來獲取所有執行計劃,結果參數基本與上文相同。
1>?queryPlanner默認參數
2>?executionStats參數
理想狀態:nReturned =?totalKeysExamined =?totalDocsExamined
stage的類型:
階段 | 說明 | 優化建議 |
---|---|---|
COLLSCAN | 全集合掃描 | 必須添加索引 |
IXSCAN | 索引掃描 | 檢查索引效率 |
FETCH | 文檔獲取 | 減少回表次數 |
SORT | 內存排序 | 添加排序索引 |
LIMIT | 結果限制 | - |
SKIP | 結果跳過 | 避免大數據集skip |
COUNT_SCAN | 計數掃描 | 高效計數 |
5、慢查詢分析
慢查詢:
-
定義:執行時間超過設定閾值的操作(默認100ms)
-
范圍:包括查詢、更新、刪除、聚合等所有數據庫操作
-
關鍵指標:執行時間、掃描文檔數、返回文檔數、索引使用情況
5.1 開啟慢查詢記錄
// 設置慢查詢閾值(單位:毫秒)
db.setProfilingLevel(1, { slowms: 50 }) // 查看當前配置
db.getProfilingStatus()
/* 輸出:
{"was": 1,"slowms": 50,"sampleRate": 1.0
}
*/
參數 | 默認值 | 說明 | 生產建議 |
---|---|---|---|
slowms | 100 | 慢查詢閾值(毫秒) | 50-100ms |
sampleRate | 1.0 | 采樣率(1.0=記錄所有慢查詢) | 0.5(高負載系統) |
profile | 0 | 0=關閉,1=慢查詢,2=所有操作 | 1 |
配置文件設置(mongod.conf):
operationProfiling:mode: slowOp # 僅記錄慢查詢slowOpThresholdMs: 50 # 50ms閾值slowOpSampleRate: 0.5 # 50%采樣率
5.2 慢查詢日志分析
查看慢查詢日志:
// 按執行時間倒序查看
db.system.profile.find().sort({ millis: -1 }).limit(5)
關鍵日志字段解析:
字段 | 說明 | 優化關注點 |
---|---|---|
op | 操作類型(query/update/remove) | 高頻操作類型 |
ns | 命名空間(database.collection) | 熱點集合 |
millis | 執行時間(毫秒) | >100ms需優化 |
keysExamined | 掃描索引鍵數量 | 對比nreturned |
docsExamined | 掃描文檔數量 | 過高需索引優化 |
nreturned | 返回文檔數量 | 對比keysExamined |
planSummary | 執行計劃摘要 | COLLSCAN需警惕 |
command | 完整命令(含查詢條件) | 查詢模式分析 |
慢查詢特征分析:
// 分析不同操作的慢查詢分布
db.system.profile.aggregate([{ $group: { _id: "$op", count: { $sum: 1 },avgTime: { $avg: "$millis" },maxTime: { $max: "$millis" }}}
])// 分析TOP慢查詢集合
db.system.profile.aggregate([{ $group: { _id: "$ns", count: { $sum: 1 },queries: { $push: { query: "$command", time: "$millis" } }}},{ $sort: { count: -1 } },{ $limit: 3 }
])
之后通過4分析執行計劃