武林內功,資料庫的索引
想把Mongodb真正的使用好,不是那麼簡單,不能只會增刪改查,還需要練習內功。
內功在武俠小說裡面是一個人發展強大起來的重要基礎,在我們Mongodb中練習內功也有這樣的作用。
開始今天的內功學習。
為什麼需要索引
索引:提高查詢效率最有效的手段。是解決查詢速度緩慢而退出的一種特殊的資料結構,以易於遍歷的形式儲存部分資料內容;索引資料儲存在記憶體當中,同樣加快了索引查詢資料的效率。
從索引的簡介中瞭解兩個個知識點:
● 目的提高查詢速度。● 索引儲存在記憶體當中。
索引針對的是查詢速度緩慢,資料量大特別是資料量在百萬級別,千萬級別以及以上的資料量。
索引能大大減少查詢時間的損耗。
eg:自己寫過一段Monodb中的關聯查詢,資料表資料在百萬級別,沒有使用索引的時刻查詢時間在7s,使用索引後查詢時間是0.3s。效率大大提高。
Mongodb的索引機制
在往Mongodb中插入文件,每個文件都會經過底層的儲存引擎持久化操作之後,會展示一個位置資訊。
通過這個位置 資訊,就能從儲存引擎中讀取到資料。不同的儲存引擎處處位置的資訊不同。選擇合適的引擎也能幫助我們快速的查詢資料。
eg: wiredtiger引擎生成一個KEY值,通過KEY去訪問對應的文件。mmapv1引擎裡面位置資訊是通過檔案id與檔案內的偏移量決定的。
索引的型別
在Mongodb中有很多種索引支援,包含以下索引型別:單欄位索引,聯合索引,多key索引,文字索引, 地理位置索引,雜湊索引.不同的索引型別支援不同型別的資料格式和查詢需求。
單欄位索引
單欄位索引是針對單個欄位進行設定索引的操作。
//建立索引的語法
db.getCollection('test').createIndex({name:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1.0
}
數字1 是索引裡面的資料按照升序進行排序,需要按照降序排序的索引可以寫-1
db.getCollection('test').createIndex({name:-1})
程式碼中針對name欄位進行了建立索引,特別是Mongodb的主鍵_Id索引也是單欄位索引。
聯合索引
聯合索引在單欄位索引上進行了多個欄位操作,將多個欄位合併為一個索引的聯合索引。
//建立索引的語法還是一樣的。
db.getCollection('test').createIndex({name:1,phone:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1.0
}
在查詢欄位中引入聯合索引,在查詢語句操作時需要按照聯合索引的順序進行查詢,否則不能走索引的操作。
eg:我們建立索引時name在前 phone在後。
//find操作
db.getCollection('test').find({name:"qiiq"})
db.getCollection('test').find({name:"qiiq",phone:12512135})
這兩種操作是能走聯合索引。
//下面兩種操作時不能走聯合索引
db.getCollection('test').find({phone:12512135,name:"qiiq"})
db.getCollection('test').find({phone:12512135})
多key索引
多key索引:當內容是陣列或者list集合建立的一種索引。該索引會為陣列中的每個欄位建立索引。
子文件索引
該索引用來嵌入子文件中的欄位進行建立索引。操作也可以有複合索引,單欄位索引。
db.getCollection('test').createIndex({"user.name":1})
索引的屬性
在Mongodb中不僅支援多個型別的索引,還能對索引增加一些額外的屬性。
● 唯一索引:在Mongodb中_id就是利用單欄位索引加唯一索引的屬性,構成的。● 部分索引(3.2版本之後新增):僅索引符合指定過濾器表示式集合中的文件。部分索引有較低的儲存要求,降低索引的建立與維護。
● 稀疏索引: 確保索引僅包含具有索引欄位的文件的條目。會跳過沒有索引欄位的文件。
● TTL索引:在一定時間後自動從集合中刪除文件的一種索引。
索引的操作
索引的操作包含 建立,檢視 ,刪除,重建操作。
索引的建立
我們在前面的操作操作中已經使用索引的建立
db.getCollection('test').createIndex({"user.name":1})
db.collection.createIndex(keys,選項)
-
keys,要建立索引的引數列表。如:{KEY:1},其中key表示欄位名,1表示升序排序,也可使用使用數字-1降序。
-
options,可選引數,表示建立索引的設定。可選值如下:
● unique,Boolean,建立唯一索引。預設值 false。
● name,String,指定索引的名稱。如果未指定,MongoDB會生成一個索引欄位的名稱和排序順序串聯。
● dropDups,Boolean,建立唯一索引時,如果出現重複刪除後續出現的相同索引,只保留第一個。
● sparse,Boolean,對文件中不存在的欄位資料不啟用索引。預設值是 false。
● v,index version,索引的版本號。
● weights,document,索引權重值,數值在 1 到 99,999 之間,表示該索引相對於其他索引欄位的得分權重。
檢視索引
getIndexes()檢視集合的所有索引。
db.getCollection('test').getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.test"
},
{
"v" : 2,
"key" : {
"name" : 1.0
},
"name" : "name_1",
"ns" : "test.test"
},
{
"v" : 2,
"key" : {
"name" : 1.0,
"phone" : 1.0
},
"name" : "name_1_phone_1",
"ns" : "test.test"
}
]
totalIndexSize()檢視集合索引的總大小。
db.getCollection('test').totalIndexSize()
69632 //單位位元組
索引的優化
慢查詢檢視
在mysql資料庫中,有慢查詢語句的展示,在Mongodb中也有這樣的實現名字是Profiling。
更改Mongodb的閾值,有三個級別的性質。
● 1 根據處理時間將超過閾值的請求記錄都記錄到system.profile集合中。
● 2 所有記錄都將記錄到集合system.profile中。
在隨著業務的發展,剛開始建立的索引可能不符合現在的業務需求。索引的數量並不是越多越好。
索引能幫助我們提高查詢的效能,但是會影響到插入和更新的效能。寫入與更新操作每次都需要把索引更新。
在此就可以根據慢請求的日誌,進行索引建立的調整。
索引分析
Mongodb中有一個命令explain();幫助我們進行查詢的慢分析。
db.getCollection("test").find().explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.test",
"indexFilterSet" : false,
"parsedQuery" : {},
"winningPlan" : {
"stage" : "COLLSCAN", //代表的是進行的全盤掃描,沒有利用到索引。當然也是查詢條件中沒有指定條件語句所致
"direction" : "forward"
},
"rejectedPlans" : []
},
"serverInfo" : {
"host" : "237ae74dd4d9",
"port" : 27017,
"version" : "4.0.3",
"gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c"
},
"ok" : 1.0
}
在name欄位增加索引,執行查詢計劃。
db.getCollection("test").find({"name":"frq"}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.test",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "frq"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"name" : 1.0,
"phone" : 1.0
},
"indexName" : "name_1_phone_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : [],
"phone" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"frq\", \"frq\"]"
],
"phone" : [
"[MinKey, MaxKey]"
]
}
}
},
"rejectedPlans" : [
{
"stage" : "FETCH", 執行完索引後,進行FETCH,讀取出最終的
"inputStage" : {
"stage" : "IXSCAN", // 重點是這裡 用到了索引欄位,先在索引中查詢。
"keyPattern" : {
"name" : 1.0
},
"indexName" : "name_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"name" : []
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"name" : [
"[\"frq\", \"frq\"]"
]
}
}
}
]
},
"serverInfo" : {
"host" : "237ae74dd4d9",
"port" : 27017,
"version" : "4.0.3",
"gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c"
},
"ok" : 1.0
}
原文釋出時間為:2018-11-5
本文作者:琪琪
相關文章
- 資料庫內功心法:資料庫基本理論資料庫
- idea內建資料庫DataGrip + 索引Idea資料庫索引
- mysql資料庫的索引MySql資料庫索引
- 資料庫的部分索引資料庫索引
- 資料庫索引資料庫索引
- 資料庫索引的工作原理資料庫索引
- 資料庫——對索引的理解資料庫索引
- indexedDB 資料庫 索引Index資料庫索引
- 資料庫索引原理資料庫索引
- [資料庫]索引失效資料庫索引
- 【Mysql】資料庫索引,百萬資料測試索引效果MySql資料庫索引
- SAP中的資料庫表索引資料庫索引
- 資料庫索引背後的資料結構資料庫索引資料結構
- MySQL資料庫之索引MySql資料庫索引
- 概覽資料庫索引資料庫索引
- 玩轉資料庫索引資料庫索引
- 資料庫索引層級資料庫索引
- 資料庫之建立索引資料庫索引
- 資料庫系列:字首索引和索引長度的取捨資料庫索引
- MySQL資料庫索引簡介MySql資料庫索引
- 資料庫索引選擇策略資料庫索引
- mongodb資料庫如何建立索引?MongoDB資料庫索引
- 將資料庫中資料匯入至solr索引庫資料庫Solr索引
- 資料庫表的唯一索引問題資料庫索引
- 你真的會使用資料庫的索引嗎?資料庫索引
- 資料庫查詢和資料庫(MySQL)索引的最佳化建議資料庫MySql索引
- MySQL 資料庫-索引注意事項MySql資料庫索引
- 關係型資料庫之索引資料庫索引
- 學習資料庫索引機制資料庫索引
- [貝聊科技]理解資料庫索引資料庫索引
- 資料庫索引融會貫通資料庫索引
- 資料庫索引分裂 問題分析資料庫索引
- H2資料庫文件索引資料庫索引
- 程式設計師內功修煉之資料結構程式設計師資料結構
- Oracle資料庫中的不可見索引 invisible indexOracle資料庫索引Index
- Mysql資料庫是如何通過索引定位資料MySql資料庫索引
- 武林大會之國產資料庫風雲榜-2021年11月資料庫
- 資料庫兩大神器【索引和鎖】資料庫索引