目录
摘要
默认索引,单列索引,指定索引名,索引方向,组合索引,唯一索引(重复值),后台创建索引,删除单个索引,删除所有索引,查询所有索引,查询指定集合的索引,exxplain,hint,建立地理位置索引,near,geoNear,within(box,center),系统剖析器
索引
特点
- 优化查找,插入会略慢
何时使用索引
- 当查询条件总是带有某一个键时
- 当查询仅使用一个键时
默认索引
在创建任何一个集合时,Mongo 会自动在 _id
上建立索引。
单列索引
db.test.ensureIndex( { "x" : 1 } , { "name" : "x_inx" } )
1
或-1
表示索引方向,多个键上建立索引时需要考虑索引方向。- 第二个参数为可选,表示索引名。
组合索引
db.test.ensureIndex( { "x" : 1, "y" : -1 } )
唯一索引
db.phones.ensureIndex(
{ display : 1 },
{ unique : true, dropDups : true}
)
dropDups
表示删除重复值,在创建唯一索引时非常有用,否则的话一旦当前集合中该列有重复数据则会创建失败。background
表示在后台创建索引,产品环境时应该这么做。background : 1
。
删除索引
删除单个索引
db.test.dropIndex( { "x" : 1 } )
删除所有索引
db.test.dropIndexes()
查询索引
查询所有索引
db.system.indexes.find()
查询指定集合的索引
db.test.getIndexes()
explain 和 hint
explain
explain
用于游标上,返回一个文档而不是游标,其会返回查询的使用情况
db.test.find ( { "x" : { $exists : 1 } } ).explain()
返回的结果
cursor
是否使用索引,值为BasicCursor
就是没有使用索引- nscanned 查询了多少文档
- n 返回的文档数
- millis 查询耗时
hint
hint
用于强制使用索引,大部分情况下没有必要
db.test.find ( { "x" : { $exists : 1 } } ).hint( { "x" : 1} )
索引管理
- 索引的元信息都被保存在
system.indexes
集合中,这是一个只读集合 - 在
system.namespaces
为每一个集合保留两个文档,一个对应集合本身,一个对应集合的索引 - 为已有文档创建索引比创建索引后再插入所有文档要稍快
db.comments.totalIndexSize()
可以查看所有索引是否都在内存中。
地理空间索引
建立索引
db.test.ensureIndex( { "mygps" : "2d" } )
其中 mygps
键对应的值必须是键值对,如 “[10, 20]” 或 “{“x” : 30, “y” : -30}”。
默认的,MongoDB 假设你索引的是经度/维度,因此配置了一个从 “-180” 到 “180” 的取值范围。要想改变的话需要修改 ensureIndex
第二个参数。
db.places.ensureIndex( { loc : "2d" } , { min : -500 , max : 500 } )
$near
db.test.find( { "gps" : { $near : [ 20, 20 ] } } )
不指定 limit
的情况下,默认返回由近到远的的 100 个文档。
geoNear
geoNear
同时会返回到查询点的距离,距离的单位与插入的数据有关
db.runCommand( { geoNear: "test", near: [40, -73], num: 100})
$within
概述
$within
用于查询指定形状。
$box
矩形
db.test.find( {
"gps" : { $within : { $box : [ [5, 5], [20, 20] ]} }
} )
参数为闭区间
$center
圆形
db.test.find( {
"gps" : { $within : { $center : [ [5, 5], 30 ]} }
} )
参数为圆心及半径
注意事项
- 默认每个集合的最大索引数为 64 个。
- 如果常常需要查询一半以上的集合,那么表扫描可能比索引要快。
系统剖析器 System Profiler
级别
- 级别 1 保留超过 100 毫秒的查询
- 级别 2 保留所有查询
设置级别
db.setProfilingLevel(2)
设置级别后需要保留的查询会被保留在 system.profile
中。
查询记录
db.system.profile.find()