索引通常能夠極大的提高查詢的效率。在系統中使用查詢時,應該考慮建立相關的索引。
索引是一種資料結構,他搜集一個集合中文檔特定欄位的值。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 圓形尋找(注意這裡是數組傳遞)