一、索引操作
说明,下面的内容举例时,以"dailyTrip"collection为例。 字段内容如下:
{ "_id" : ObjectId("63ec5a971ddbe429cbeeffe3"), // object id "car_type" : "Gett", // string "date" : ISODate("2016-04-01T00:00:00.000+0000"), //ISODate "trips" : 0.0, // number "monthly" : "NA", // string "parent_type" : "Ride-hailing apps", // string "monthly_is_estimated" : true, // boolean "geo" : { // object "$concat" : [ // array "$parent_type", "$grouping" ] } }
执行看看有5.17万条数据
1. 索引类型
-
单列索引: 在一个字段上创建的索引。
-
复合索引:由多个字段组合一起创建的索引。使用的时候要注意最左前缀原则,避免索引无法命中(失效)。
-
文本索引(全文索引)和空间索引(GEO索引),不常用,这里不讲,具体自行网上查询。
2. 查看
语法:
db.Collection.getIndexs();
返回内容说明:
[ // 返回一个数组,内容是所有索引 { "v" : 2.0, // 索引版本,可忽略 "key" : { // 索引加在哪个字段,以及排序 "_id" : 1.0 // _id 是字段, 1.0是正序(升序), -1.0是倒序(倒序) }, "name" : "_id_" // 索引名,如果添加的时候没有指定,Mongo会自动生成。 } ]
举例:
可以看到返回一个name为 _id_的索引。 作用于 _id上, 升序排列。
3. 创建
语法:
db.collection.createIndex(keys, options) // 组合索引 db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } ) // 其中 <fieldN>是字段名 <typeN>是排序 注意:3.0.0 版本之前创建索引方法为 db.collection.ensureIndex()。 5.0之后ensureIndex() 已被移除。
举例:
// 创建单字段索引 db.dailyTrip.createIndex({"car_type":1}); // 返回结果 { "numIndexesBefore" : 1.0, // 新建索引前的索引数 "numIndexesAfter" : 2.0, // 新建索引后的索引数 "createdCollectionAutomatically" : false, // 一般情况下,如果该集合存在,这里就是返回false。如果指定的集合不存在,MongoDB 默认情况下会自动创建该集合,并在该集合上创建索引,此时返回true。 "ok" : 1.0 // 创建结果 1.0则是成功。返回0则说明报错了。 } // 如果创建的字段的索引已经存在,则返回如下 { "numIndexesBefore" : 2.0, "numIndexesAfter" : 2.0, "note" : "all indexes already exist", // 提示已经存在 "ok" : 1.0 } // 创建复合索引 db.dailyTrip.createIndex({"parent_type":1, "car_type":1}) // 也可以指定自定义索引名 db.dailyTrip.createIndex({"parent_type":1, "car_type":1}, { name: "inx_parantType_carType" }) // 这里自己试验 // 来自官方文档 https://www.mongodb.com/docs/manual/reference/command/createIndexes/
创建完毕后,再次查看当前索引情况
4. 删除
语法:
删除指定集合中所有索引: db.collection.dropIndexes(); 删除指定集合中的具体索引: db.collection.dropIndex("索引名称");
举例:
// 删除指定索引 db.dailyTrip.dropIndex("car_type_1"); // 返回结果 { "nIndexesWas" : 3.0, // 指示在删除索引之前集合中存在的索引数量。 "ok" : 1.0 } // 删除所有,自行尝试。 注意, 主键_id的索引是不会也不能被删除的。 db.collection.dropIndexes();
5. 修改
无法直接修改,如果需要调整索引字段、名称、组合索引的顺序,需要先删除原来索引,再新建索引。
6. 索引使用原则
-
选择经常被查询的字段来创建索引。那些在查询条件、排序和聚合操作中频繁出现的字段是最佳选择。
-
选择合适的、常用作查询条件的字段,综合判断是否可以使用复合索引,如果可以优先复合索引。 比如多数情况是按照字段A、B、C或者A、B条件去查询,那么可以优先考虑基于字段A、B、C创建复合索引。 使用复合索引来覆盖多个查询条件,以减少索引的数量。
-
尽量使用索引覆盖,和MySQL中的索引覆盖是类似的。 覆盖索引是指索引包含了查询所需的字段,从而避免了查询需要访问实际文档。这可以提高查询性能,减少IO操作。 其实这里和上面的复合索引是相关的。
-
其他的还有包括使用Explain去查看执行计划、定期监控性能、删除冗余无用的索引之类的,不一而足。 上面是基于实际开发经验得出的常用手段原则。
7. 索引失效的情况
-
查询条件不满足索引前缀: 例如,复合索引是
{ a: 1, b: 1 }
,而查询条件只包含{ b: 1 }
,则该复合索引将无法被使用。 -
数据类型不匹配: 如果查询条件中的数据类型与索引字段的数据类型不匹配,索引可能无法被使用。例如,如果索引字段是数字类型,而查询条件中使用了字符串类型的值,索引将无法被使用。
// 类似Mysql中的隐式转换会使索引失效。
-
索引选择性低: 索引的选择性是指索引中不同值的唯一性程度。如果索引的选择性很低,即索引中的值几乎都相同,那么使用该索引可能不会带来明显的性能提升。
// 这里其实是说索引列的值的区分度,如果重复度过高,那么使用索引的性能可能不如不用,索引底层优化器可能不选择使用索引。假如字段gender只有2个值,male和female,其中一半数据是male,另一半是female,此时用gender索引,还不如不用。
-
使用不支持的操作符: 某些查询操作符可能无法使用索引。例如,正则表达式查询、模糊查询(如
$text
操作符)等可能无法充分利用索引。 -
数据量较小: 当集合中的数据量较小时,MongoDB 可能会选择全表扫描而不使用索引,因为全表扫描可能更快。
// 类似mysql中,一般建议小于1000条就不加索引,因为索引有额外开销。
-
索引过期或损坏: 如果索引过期或损坏,MongoDB 将无法使用该索引。
-
索引被禁用: 如果在查询时禁用了索引,或者索引的存储引擎不支持该查询,索引将无法被使用。
-
索引尺寸过大: 如果索引的尺寸超过了 MongoDB 的限制,该索引可能无法被使用。
使用 explain()
方法可以查看查询计划和索引使用情况,帮助识别索引失效的原因,并进行相应的优化。
接下来对Explain方法做说明解释。
标签:1.0,MongoDB,Explain,db,查询,索引,详解,type,id From: https://www.cnblogs.com/zaoyu/p/17623197.html