3.5 索引(重点)
任何数据库中,索引都是一种提升数据库检索性能的手段,这一点在MongoDB数据库中同样是存在的,MongoDB数据库里面存在两种索引创建:一是自动创建,另外是手工创建。
范例:重新准备一个新的简单集合
此时在students集合上并没有设置任何的索引,下面通过getIndexes()函数来观察在students集合里面已经存在的索引内容。
范例:查询默认状态下的students集合的索引内容
db.students.getIndexes()
会发现存在一个“_id”列的索引内容。"V"表示索引版本;"_id" : 1中的1表式升序排序;"name"是在字段"_id"后面加上下划线;"ns"是指在test.students集合下。
创建自己的索引:
语法:db.集合名称.ensureIndex({列 : 1})
设置的1表示索引按照升序的方式进行排列,如果使用降序设置“-1”。
范例:创建一个索引,在age字段上设置一个降序索引
db.students.ensureIndex({"age" : -1})
此处的索引名并没被创建,是自动命名的。命名规范:“字段名称_索引的排序模式”
"name" : "age_-1"中name由字段名age加上下划线,再加上索引排序模式(-1表示降序)组成。
范例:针对当前的age字段上的索引做一个分析
db.students.find({"age" : 19}).explain()
表示界定值;"IXSCAN"表示索引扫描(index scan)。
范例:针对score字段上设置查询(不使用索引号)
db.students.find({"score" : {"$gt" : 90}}).explain()
"COLLSCAN"表示集合扫描(collection scan),即全表扫描。
此时在score字段上并没有设置索引,所以当前的索引形式变为全集合扫描的模式。
范例:年龄和成绩一起执行判断查询
db.students.find({"$or" : [{"age" : {"$gt" : 19}}, {"score" : {"$gt" : 90}}]}).explain()
由于age,score字段上没有索引,所以使用全表扫描,那么为了解决此时问题,可以使用一个复合索引。
db.students.ensureIndex({"age" : -1, "score" : -1}, {name : "age_-1_score_-1_index"})
范例:使用默认索引
db.students.find({"age" : 19, "score" : 90}).explain()
但是如果换到条件之中:
db.students.find({"$or" : [{"age" : {"$gt" : 19}}, {"score" : {"$gt" : 90}}]}).explain()
现在发现并没使用索引,所以这个时候看能否强制使用一次索引。hint()函数为强制使用索引操作。
范例:强制使用索引
db.students.find({"$or" : [{"age" : {"$gt" : 19}}, {"score" : {"$gt" : 90}}]}).hint({"age" : -1, "score" : -1}).explain()
如果正常来讲,这个代码不可能调用默认的索引执行,但是我们觉得不好,所以需要使用hink()强制使用索引。由于此时在age和score两个字段上已经设置了符合索引,现在使用的就是默认的符合索引。
将降序变为升序,即-1变为1:
db.students.find({"$or" : [{"age" : {"$gt" : 19}}, {"score" : {"$gt" : 90}}]}).hint({"age" : 1, "score" : 1}).explain()
这样是错误的。hint()的操作必须用指定字段上绑定的索引结果来运行,指定字段age,score本来绑定的是-1,不能用1来运行。
但是如果在一个集合里设置过多的索引,会导致性能下降,可以删除索引。
范例:删除一个索引
db.students.dropIndex({"age" : -1, "score" : -1})
只是一个一个删除索引也会很麻烦,所以提供有删除全部索引的操作。
范例:删除全部索引
db.students.dropIndexes()
所谓删除全部索引指的就是非“_id”的索引,即所有自定义索引。