索引通常能夠極大的提高查詢的效率。在系統中使用查詢時,應該考慮建立相關的索引。
索引是一種數據結構,他搜集一個集合中文檔特定字段的值。MongoDB的查詢優化器能夠
使用這種數據結構來快速的對集合(collection)中的文檔(collection)進行尋找和排序,
准確來說,這些索引是通過B-Tree索引來實現的。
1.創建簡單索引
數據准備index.js,創建books文檔並插入200000條數據,如下:
for(var i=0;i<200000;i++){
db.books.insert({number:i,name:i+"book"})
}
1.先檢驗一下查詢性能
var start = new Date()
db.books.find({number:65871})
var end = new Date()
end - start
2.為number 創建索引
db.books.ensureIndex({number:1})
3.再執行第一部的代碼可以看出有數量級的性能提升
2.索引使用需要注意的地方
1.創建索引的時候注意1是正序創建索引-1是倒序創建索引
2.索引的創建在提高查詢性能的同事會影響插入的性能對於經常查詢少插入的文檔可以考慮用索引
3.符合索引要注意索引的先後順序
4.每個鍵全建立索引不一定就能提高性能呢索引不是萬能的
5.在做排序工作的時候如果是超大數據量也可以考慮加上索引用來提高排序的性能
3.創建索引同時指定索引的名字
db.books.ensureIndex({name:-1},{name:”bookname”})
4.唯一索引
4.1如何解決文檔books不能插入重復的數值
建立唯一索引
db.books.ensureIndex({name:-1},{unique:true})
試驗
db.books .insert({name:”1book”})
5.剔除重復值
5.1如果建議唯一索引之前已經有重復數值如何處理
db.books.ensureIndex({name:-1},{unique:true,dropDups:true})
6.Hint
6.1如何強制查詢使用指定的索引呢?
db.books.find({name:"1book",number:1}).hint({name:-1})
指定索引必須是已經創建了的索引
7.Expain
7.1如何詳細查看本次查詢使用那個索引和查詢數據的狀態信息
db.books.find({name:"1book"}).explain()
返回結果,如下所示:
> db.books.find({name:"1book"}).explain()
{
"cursor" : "BtreeCursor name_1",
"isMultiKey" : false,
"n" : 1,
"nscannedObjects" : 1,
"nscanned" : 1,
"nscannedObjectsAllPlans" : 1,
"nscannedAllPlans" : 1,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"name" : [
[
"1book",
"1book"
]
]
},
"server" : "PC-20110917QHJT:27017"
}
"cursor" : "BtreeCursor name_1" 使用索引
"nscanned" : 1 查到幾個文檔
"millis" : 0 查詢時間,0是很不錯的性能
二、索引管理
8、system.indexes
8.1、在shell中,查看數據庫已經建立的索引。如下:
db.system.indexes.find()
db.system.namespaces.find()
9、後台執行
9.1、執行創建索引的過程會暫時鎖表問題,如何解決?
為了不影響查詢,我們可以讓索引的創建過程在後台執行。
db.books.ensureIndex({number:1},{true})
10、刪除索引
10.1、批量和精確刪除索引
db.runCommand({dropIndexes:"books",index:"name_1"}) 精確刪除索引
db.runCommand({dropIndexes:"books",index:"*"}) 批量刪除索引
三、空間索引
11、mongoDB提供強大的空間索引,可以查詢出一定范圍的地理坐標。示例如下:
准備數據map.txt,如下圖:
var map = [{
"gis" : {
"x" : 185,
"y" : 150
}
},{
"gis" : {
"x" : 70,
"y" : 180
}
},{
"gis" : {
"x" : 75,
"y" : 180
}
},{
"gis" : {
"x" : 185,
"y" : 185
}
},{
"gis" : {
"x" : 65,
"y" : 185
}
},{
"gis" : {
"x" : 50,
"y" : 50
}
},{
"gis" : {
"x" : 50,
"y" : 50
}
},{
"gis" : {
"x" : 60,
"y" : 55
}
},{
"gis" : {
"x" : 65,
"y" : 80
}
},{
"gis" : {
"x" : 55,
"y" : 80
}
},{
"gis" : {
"x" : 0,
"y" : 0
}
},{
"gis" : {
"x" : 0,
"y" : 200
}
},{
"gis" : {
"x" : 200,
"y" : 0
}
},{
"gis" : {
"x" : 200,
"y" : 200
}
}]
for(var i = 0;i
db.map.insert(map[i])
}
首先,添加2D索引(默認會建立一個[-180,180]之間的2D索引)
db.map.ensureIndex({"gis":"2d"},{min:-1,max:201})
11.1、查詢出距離點(70,180)最近的3個點
db.map.find({"gis":{$near:[70,180]}},{gis:1,_id:0}).limit(3)//$near操作符表示中心點;如果沒有指定limit,其默認值為100。
11.2、查詢以點(50,50)和(190,190)為對角線的正方形中的所有點
var box=[[50,50],[190,190]];//定義一個矩形區域
db.map.find({"gis":{"$within":{"$box":box}}},{gis:1,_id:0})//$box 矩形查找
11.3、查詢出以圓心為(55,80),半徑為50,規則下的圓心面積中的點
var center=[55,80];//定義中心點
var radius=50;//定義半徑
db.map.find({"gis":{"$within":{"$center":[center,radius]}}});//$center 圓形查找(注意這裡是數組傳遞)