轉載地址:http://forum.foxera.com/mongo…
索引對於一個資料庫的影響相信大家一定了解,如果一個查詢命令進入到資料庫中後,查詢優化器沒有找到合適的索引,那麼資料庫會進行全集合掃描(在RDBMS中也叫全表掃描),全集合查詢對於效能的影響是災難性的。沒有索引的查詢就如同在詞典那毫無規律的海量詞彙中獲得某個你想要的詞彙,但這個詞典是沒有目錄的,只能通過逐頁來查詢。這樣的查詢可能會讓你耗費幾個小時的時間,但如果要求你查詢詞彙的頻率如同使用者訪問的頻率一樣的話。。。嘿嘿,我相信你一定會大喊“老子不幹了!”。顯然計算機不會這樣喊,它一直是一個勤勤懇懇的員工,不論多麼苛刻的請求他都會完成。
在MongoDB中索引的型別與RDBMS中大體一致,我們不做過多重複,我們來看一下在MongoDB中如何才能更高效的利用索引。
1.索引越少越好
索引可以極大地提高查詢效能,那麼索引是不是越多越好?答案是否定的,並且索引並非越多越好,而是越少越好。每當你建立一個索引時,系統會為你新增一個索引表,用於索引指定的列,然而當你對已建立索引的列進行插入或修改時,資料庫則需要對原來的索引表進行重新排序,重新排序的過程非常消耗效能,但應對少量的索引壓力並不是很大,但如果索引的數量較多的話對於效能的影響可想而知。所以在建立索引時需要謹慎建立索引,要把每個索引的功能都要發揮到極致,也就是說在可以滿足索引需求的情況下,索引的數量越少越好。
一. 隱式索引
//建立複合索引
db.test.ensureIndex({"age": 1,"no": 1,"name": 1 })
我們在查詢時可以迅速的將age,no欄位進行排序,隱式索引指的是如果我們想要排序的欄位包含在已建立的複合索引中則無需重複建立索引。
db.test.find().sort("age": 1,"no": 1)
db.test.find().sort("age": 1)
如以上兩個排序查詢,均可使用上面的複合索引,而不需要重新建立索引。
二. 翻轉索引
//建立複合索引
db.test.ensureIndex({"age": 1})
翻轉索引很好理解,就是我們在排序查詢時無需考慮索引列的方向,例如這個例子中我們在查詢時可以將排序條件寫為”{`age`: 0}”,依舊不會影響效能。
2.索引列顆粒越小越好
什麼叫顆粒越小越好?在索引列中每個資料的重複數量稱為顆粒,也叫作索引的基數。如果資料的顆粒過大,索引就無法發揮該有的效能。例如,我們擁有一個”age”列索引,如果在”age”列中,30歲佔了40%,如果現在要查詢一個30歲,名叫”Tom”的人,我們則需要在表的40%的資料中查詢,索引的作用大大降低。所以,我們在建立索引時要儘量將資料顆粒小的列放在索引左側,以保證索引發揮最大的作用。