数据量较大时,使用索引可以大大加快查询速度。
- 查看索引
db.test_collection.getIndexes()
- 创建索引
db.test_collection.ensureIndex({x:1})
索引种类
- _id 索引(自动创建)
- 单键索引(比较变通的索引,不会自动创建)
- 多键索引(与单。。区别在于字段的值是单一,还是数组)
db.test_collection.ensureIndex({x:1})
db.test_collection.insert({x:[1,4,5,4]}) //就成了多键索引
- 复合索引(当查询条件不只一个时,就需要建立复合索引)
db.collection.ensureIndex({x:1,y:1})
- 过期索引(一段时间会过期,相应数据也会被删除)
比较适合登录信息和日志信息。
db.collection.ensureIndex({time:1},{expireAfterSeconds:10})
存储在过期索引的值必须是指定的时间类型,必须是ISODate或者ISODate数组,不能使用时间戳,否则不能被自动删除 ;如果ISODate是数组,则最小时间进行删除;不能是复合索引;删除时间是不精确的(每60s跑一次,删除也要一些时间)。 - 全文索引(对字符串与字符串数组创建全文可搜索的索引)
适用情况:{author:”“,title:”“,article:”“}
db.articles.ensureIndex({key:"text"})
db.articles.ensureIndex({key1:"text",key2:"text"})
db.articles.ensureIndex({key:"text"})
查询:
db.articles.find({$text:{$search:"coffee"}})
db.articles.find({$text:{$search:"aa bb cc"}}) //或查询
db.articles.find({$text:{$search:"aa bb -cc"}}) //不包含cc串
db.articles.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}}) //与查询语句,用引号(这里要用斜线转义)
与百度查询相同,相似度越大的在前面的查询(使用$meta):
{score:{$meta:"textScore"}}
db.articles.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}})
查询数据中多了一个score字段,表示相似度
进行排序:
db.articles.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}})
使用限制:每次查询只能指定一个 text查询; text查询不能出现在 nor查询中;含有 text,hint不再起作用(强制指定使用某索引进行性能测试);不支持中文。 地理位置索引
将一些点的位置存储在MongoDB中,创建索引后,可以按照位置来查找其他点。
子分类:2d索引,用于存储和查找平面上的点;
查找方式:
a. 查找距离某个点一定距离内的点。
ensureIndex({w:"2d"}) //创建
经度[-180,180]纬度[-90,90]
insert({w:[1,1]}) //插入数据
find({w:{$near:[1,1]}}) //与[1,1]距离最近的点
find({w:{$near:[1,1],$maxDistance:10}}) // 设置最大距离范围
b. 查找包含在某个区域内的点。
find({w:{$geoWithin:{$box:[[0,0],[3,3]]}}}) //在矩形中的点
find({w:{$geoWithin:{$center:[[0,0],4]}}}) //在圆中的点
find({w:{$geoWithin:{$polygon:[[0,0],[0,1],[2,5],[6,1]]}}}) //在多边形中的点
geoNear查询:
db.runCommand({geoNear:<collection>,near:[x,y],minDistance:d1,maxDistance:d2,num:n1(返回数目)})
db.runCommand({geoNear:"location",near:[1,2],maxDistance:10,num:2})
2dsphere索引,用于存储和查找球面上的点。
ensureIndex({w:"2dsphere"})
{type:" ",coordinates:[<coodinates>]} //位置表示
查询与2d类似,并且支持$minDistance 与 $maxDistance,还支持交叉点
索引属性
- name
一般索引 x_1 或x_-1//升序与降序 ;复合索引为x_1_y_-1;可能超125字节限制自定义索引名字:ensureIndex({x:1,y:1,z:1,m:1},{name:"normal_index
- 唯一性,unique指定:
ensureIndex({},{unique:true/false})
- 稀疏性,sparse指定(在不包括索引数据中不必创建索引,节约空间,增大查询速度):
ensureIndex({},{sparse:true})
但在$exists(用于查找一个字段存在与不存在的数据)中出现隐患
find({m:{$exists:true}}) //只查找m存在的字段
不能在稀疏索引上查找不存在的记录。 - 是否定期删除,expireAfterSeconds指定:
TTL,过期索引
索引构建情况分析
- 好处:加快索引相关的查询。
- 劣势:增加磁盘空间消耗,降低写入性能。
评判当前索引构建情况
- mongostat工具
mongostat -h 127.0.0.1:12345
其中 idx miss 较高,就说明创建了不合适的索引
各指标含义:
inserts/s 每秒插入次数
query/s 每秒查询次数
update/s 每秒更新次数
delete/s 每秒删除次数
getmore/s 每秒执行getmore次数
command/s 每秒的命令数,比如count
flushs/s 每秒执行fsync将数据写入硬盘的次数。
mapped/s 所有的被mmap的数据量,单位是MB,
vsize 虚拟内存使用量,单位MB
res 物理内存使用量,单位MB
faults/s 每秒访问失败数(只有Linux有),数据被交换出物理内存,放到swap。不要超过100,否则就是机器内存太小,造成频繁swap写入。此时要升级内存或者扩展
locked % 被锁的时间百分比,尽量控制在50%以下吧
idx miss % 索引不命中所占百分比。如果太高的话就要考虑索引是不是少了
q t|r|w 当Mongodb接收到太多的命令而数据库被锁住无法执行完成,它会将命令加入队列。这一栏显示了总共、读、写3个队列的长度,都为0的话表示mongo毫无压力。高并发时,一般队列值会升高。
conn 当前连接数
time 时间戳
Mongodb良好运行标示:
insert query update delete 较稳定,这4列数据越大说明性能越高,如果运行一定时间后,指标骤减,说明程序处理存在问题。
faults越小越好,越小说明操作失败率越低;
idx miss越小越好,越小说明索引命中率越高,Mongodb索引非常重要;
netin/netout 数据越大越好,越大说明进出数据交换越大。 - profile集合介绍
db.getProfilingLevel() //有0关闭,2开启,1记录超过slowms值的操作
db.getProfilingStatus()// { "was" : 0, "slowms" : 100 }
设置db.setProfilingLevel(2)//开启,会生成一个system.profile文档
db.system.profile.find().sort({$natural:-1}).limit(1)
开启后会影响到数据库的性能,只适用于系统的测试阶段和刚刚上线时观察阶段。 - 日志介绍
在配置文件mongod.conf下verbose=vvvvv
verbose值可以是一个v到五个v.详细程度逐渐提高 - explain分析
find({x:1}).explain()可以查询你的查询是否用了索引和查询时间,以及扫描数量。