MongoDB索引Index
標簽: MongoDB
什么是索引
索引是一種單獨的、物理的對數據庫表中一列或多列的值進行排序的一種存儲結構,它是某個表中一列或若干列值的集合和相應的指向表中物理標識這些值的數據頁的邏輯指針清單。索引的作用相當于圖書的目錄,可以根據目錄中的頁碼快速找到所需的內容。索引目標是提高數據庫的查詢效率,沒有索引的話,查詢會進行全表掃描(scan every document in a collection),數據量大時嚴重降低了查詢效率。默認情況下Mongo在一個集合(collection)創建時,自動地對集合的_id創建了唯一索引
索引類型
3.2.1 單鍵索引 (Single Field)
MongoDB支持所有數據類型中的單個字段索引,并且可以在文檔的任何字段上定義。
對于單個字段索引,索引鍵的排序順序無關緊要,因為MongoDB可以在任一方向讀取索引。
單個例上創建索引:
db.集合名.createIndex({"字段名":排序方式})
特殊的單鍵索引 過期索引 TTL ( Time To Live)
TTL索引是MongoDB中一種特殊的索引, 可以支持文檔在一定時間之后自動過期刪除,目前TTL索引只能在單字段上建立,并且字段類型必須是日期類型。
db.集合名.createIndex({"日期字段":排序方式}, {expireAfterSeconds: 秒數})
復合索引(Compound Index)
通常我們需要在多個字段的基礎上搜索表/集合,這是非常頻繁的。 如果是這種情況,我們可能會考慮在MongoDB中制作復合索引。 復合索引支持基于多個字段的索引,這擴展了索引的概念并將它們擴展到索引中的更大域。
制作復合索引時要注意的重要事項包括:字段順序與索引方向
db.集合名.createIndex( { "字段名1" : 排序方式, "字段名2" : 排序方式 } )
多鍵索引(Multikey indexes)
針對屬性包含數組數據的情況,MongoDB支持針對數組中每一個element創建索引,Multikeyindexes支持strings,numbers和nested documents
地理空間索引(Geospatial Index)
針對地理空間坐標數據創建索引。
2dsphere索引,用于存儲和查找球面上的點
2d索引,用于存儲和查找平面上的點
db.company.insert(
{
loc : { type: "Point", coordinates: [ 116.482451, 39.914176 ] },
name: "大望路地鐵",
category : "Parks"
}
) d
b.company.ensureIndex( { loc : "2dsphere" } )
參數不是1或-1,為2dsphere 或者 2d。還可以建立組合索引。
db.company.find({
"loc" : {
"$geoWithin" : {
"$center":[[116.482451,39.914176],0.05]
}
}
})
全文索引
MongoDB提供了針對string內容的文本查詢,Text Index支持任意屬性值為string或string數組元素的
索引查詢。注意:一個集合僅支持最多一個Text Index,中文分詞不理想 推薦ES
db.集合.createIndex({"字段": "text"})
db.集合.find({"$text": {"$search": "coffee"}})
哈希索引 Hashed Index
針對屬性的哈希值進行索引查詢,當要使用Hashed index時,MongoDB能夠自動的計算hash值,無
需程序計算hash值。注:hash index僅支持等于查詢,不支持范圍查詢
db.集合.createIndex({"字段": "hashed"})
索引和explain 分析
索引管理
創建索引并在后臺運行
db.COLLECTION_NAME.createIndex({"字段":排序方式}, {background: true});
獲取針對某個集合的索引
db.COLLECTION_NAME.getIndexes()
索引的大小
db.COLLECTION_NAME.totalIndexSize()
索引的重建
db.COLLECTION_NAME.reIndex()
索引的刪除
db.COLLECTION_NAME.dropIndex("INDEX-NAME")
db.COLLECTION_NAME.dropIndexes()
注意: _id 對應的索引是刪除不了的
explain 分析
使用js循環 插入100萬條數據 不使用索引字段 查詢查看執行計劃 ,然后給某個字段建立索引,使用索引字段作為查詢條件 再查看執行計劃進行分析
explain()也接收不同的參數,通過設置不同參數我們可以查看更詳細的查詢計劃。
queryPlanner:queryPlanner是默認參數,具體執行計劃信息參考下面的表格。
executionStats:executionStats會返回執行計劃的一些統計信息(有些版本中和allPlansExecution等同)。
allPlansExecution:allPlansExecution用來獲取所有執行計劃,結果參數基本與上文相同。
queryPlanner 默認參數
executionStats參數
executionStats返回逐層分析
第一層,executionTimeMillis最為直觀explain返回值是executionTimeMillis值,指的是這條語句的執
行時間,這個值當然是希望越少越好。
其中有3個executionTimeMillis,分別是:
executionStats.executionTimeMillis 該query的整體查詢時間。
executionStats.executionStages.executionTimeMillisEstimate 該查詢檢索document獲得數據的時
間。
executionStats.executionStages.inputStage.executionTimeMillisEstimate 該查詢掃描文檔 index
所用時間。
第二層,index與document掃描數與查詢返回條目數 這個主要討論3個返回項 nReturned、
totalKeysExamined、totalDocsExamined,分別代表該條查詢返回的條目、索引掃描條目、文檔掃描
條目。 這些都是直觀地影響到executionTimeMillis,我們需要掃描的越少速度越快。 對于一個查詢,
我們最理想的狀態是:nReturned=totalKeysExamined=totalDocsExamined
第三層,stage狀態分析 那么又是什么影響到了totalKeysExamined和totalDocsExamined?是stage的
類型。
類型列舉如下
型列舉如下:
COLLSCAN:全表掃描
IXSCAN:索引掃描
FETCH:根據索引去檢索指定document
SHARD_MERGE:將各個分片返回數據進行merge
SORT:表明在內存中進行了排序
LIMIT:使用limit限制返回數
SKIP:使用skip進行跳過
IDHACK:針對_id進行查詢
SHARDING_FILTER:通過mongos對分片數據進行查詢
COUNT:利用db.coll.explain().count()之類進行count運算
TEXT:使用全文索引進行查詢時候的stage返回
PROJECTION:限定返回字段時候stage的返回
對于普通查詢,我希望看到stage的組合(查詢的時候盡可能用上索引):
Fetch+IDHACK
Fetch+IXSCAN
Limit+(Fetch+IXSCAN)
PROJECTION+IXSCAN
SHARDING_FITER+IXSCAN
不希望看到包含如下的stage:
COLLSCAN(全表掃描)
SORT(使用sort但是無index)
COUNT 不使用index進行count)
allPlansExecution參數
queryPlanner 參數和executionStats的拼接
慢查詢分析
1.開啟內置的查詢分析器,記錄讀寫操作效率
db.setProfilingLevel(n,m),n的取值可選0,1,2
0表示不記錄
1表示記錄慢速操作,如果值為1,m必須賦值單位為ms,用于定義慢速查詢時間的閾值
2表示記錄所有的讀寫操作
2.查詢監控結果
db.system.profile.find().sort({millis:-1}).limit(3)
分析慢速查詢
3. 應用程序設計不合理、不正確的數據模型、硬件配置問題,缺少索引等
4.解讀explain結果 確定是否缺少索引
MongoDB 索引底層實現原理分析
MongoDB 是文檔型的數據庫,它使用BSON 格式保存數據,比關系型數據庫存儲更方便。比如之前關系型數據庫中處理用戶、訂單等數據要建立對應的表,還要建立它們之間的關聯關系。
但是BSON就不一樣了,我們可以把一條數據和這條數據對應的數據都存入一個BSON對象中,這種形式更簡單,通俗易懂。MySql是關系型數據庫,數據的關聯性是非常強的,區間訪問是常見的一種情況,底層索引組織數據使用B+樹,B+樹由于數據全部存儲在葉子節點,并且通過指針串在一起,這樣就很容易的進行區間遍歷甚至全部遍歷。MongoDB使用B-樹,所有節點都有Data域,只要找到指定索引就可以行訪問,單次查詢從結構上來看要快于MySql
B-樹是一種自平衡的搜索樹,形式很簡單
B-樹的特點:
(1) 多路 非二叉樹
(2) 每個節點 既保存數據 又保存索引
(3) 搜索時 相當于二分查找
B+樹是B-樹的變種
B+ 樹的特點:
(1) 多路非二叉
(2) 只有葉子節點保存數據
(3) 搜索時 也相當于二分查找
(4) 增加了 相鄰節點指針
最核心的區別主要有倆,一個是數據的保存位置,一個是相鄰節點的指向。
就是這倆造成了MongoDB和MySql的差別。
(1)B+樹相鄰接點的指針可以大大增加區間訪問性,可使用在范圍查詢等,而B-樹每個節點 key 和data 在一起 適合隨機讀寫 ,而區間查找效率很差。
(2)B+樹更適合外部存儲,也就是磁盤存儲,使用-結構的話,每次磁盤預讀中的很多數據是用不上的數據。因此,它沒能利用好磁盤預讀的提供的數據。由于節點內無 data 域,每個節點能索引的范圍更大更精確。
(3)注意這個區別相當重要,是基于(1)(2)的,B-樹每個節點即保存數據又保存索引 樹的深度小,所以磁盤IO的次數很少,B+樹只有葉子節點保存,較B樹而言深度大磁盤IO多,但是區間訪問比較好。
智能推薦
oracle索引index
1.問題: 當數據庫表中存在很多條記錄,如大于10萬條時,查詢速度便成為一個問題 2.分析: 在字典中查詢指定偏旁的漢字時,先查詢目錄中指定的偏旁位置,在查詢指定筆畫的漢字,找到漢字后根據頁碼找到漢字 在書中查詢某內容時,首先在目錄中查詢所需知識點,然后根據目錄中提供的頁碼找到要查詢內容,大大縮短了查詢時間 3.解決: 可以建立類似目錄的數據庫對象,實現數據快速查詢,這就是索引 索引類似字典的和課...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
猜你喜歡
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...
styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...