MongoDB索引
索引的分类
索引设计原则
索引操作
创建索引
db.collection.createIndex(keys, options)
Parameter |
Type |
Description |
2 |
Boolean |
建索引过程会阻塞其它数据库操作 ,background可指定 以后台方式创建索引 ,即增加 "background" 可选参 数。 "background" 默认值为false。 |
unique |
Boolean |
建立的索引是否唯一。指定为true创建唯一索引。默认值 为false. |
name |
string |
索引的名称。如果未指定, MongoDB的通过连接索引的 字段名和排序顺序生成一个索引名称。 |
dropDups |
Boolean |
3.0 +版本已废弃。在建立唯一索引时是否删除重复记录, 指定 true 创建唯一索引。默认值为 false. |
sparse |
Boolean |
对文档中不存在的字段数据不启用索引;这个参数需要特 别注意 ,如果设置为true的话 ,在索引字段中不会查询出 不包含对应字段的文档。默认值为 false. |
expireAfterSeconds |
integer |
指定一个以秒为单位的数值 ,完成 TTL设定 ,设定集合的 生存时间。 |
v |
index version |
索引的版本号。默认的索引版本取决于mongod创建索引 时运行的版本。 |
weights |
document |
索引权重值 ,数值在 1 到 99,999 之间 ,表示该索引相对 于其他索引字段的得分权重。 |
default_language |
string |
对于文本索引 ,该参数决定了停用词及词干和词器的规则 的列表。 默认为英语 |
language_override |
string |
对于文本索引 ,该参数指定了包含在文档中的字段名 ,语 |
# 创建索引后台执行
db.values.createIndex({open: 1, close: 1}, {background: true})
# 创建唯一索引
db.values.createIndex({title:1},{unique:true})
查看索引
#查看索引信息
db.books.getIndexes()
#查看索引键
db.books.getIndexKeys()
查看索引占用空间
db.collection.totalIndexSize([is_detail])
删除索引
#删除集合指定索引
db.col.dropIndex("索引名称")
#删除集合所有索引 不能删除主键索引
db.col.dropIndexes()
索引类型
单键索引
db.books.createIndex({title:1})
复合索引
db.books.createIndex({type:1,favCount:1})
多键索引
db.inventory.createIndex( { ratings: 1 } )
注意 :
地理空间索引(Geospatial Index)
db.restaurant.insert({
restaurantId: 0,
restaurantName: "兰州牛肉面",
location: {
type: "Point",
coordinates: [73.97, 40.77]
}
})
创建一个2dsphere索引
db.restaurant.createIndex({location : "2dsphere"})
全文索引(Text Indexes)
MongoDB支持全文检索功能,可通过建立文本索引来实现简易的分词检索
db.reviews.createIndex( { comments: "text" } )
db.stores.insert([{
_id: 1,
name: "Java Hut",
description: "Coffee and cakes"
},
{
_id: 2,
name: "Burger Buns",
description: "Gourmet hamburgers"
},
{
_id: 3,
name: "Coffee Shop",
description: "Just coffee"
},
{
_id: 4,
name: "Clothes Clothes Clothes",
description: "Discount clothing"
},
{
_id: 5,
name: "Java Shopping",
description: "Indonesian goods"
}])
db.stores.createIndex({name: "text", description: "text"})
db.stores.find({$text: {$search: "java coffee shop"}})
Hash索引(Hashed Indexes)
db.users.createIndex({username : 'hashed'})
通配符索引(Wildcard Indexes)
db.products.insert([{
"product_name": "Spy Coat",
"product_attributes": {
"material": ["Tweed", "Wool", "Leather"],
"size": {
"length": 72,
"units": "inches"
}
}
},
{
"product_name": "Spy Pen",
"product_attributes": {
"colors": ["Blue", "Black"],
"secret_feature": {
"name": "laser",
"power": "1000",
"units": "watts",
}
}
},
{
"product_name": "Spy Book"
}])
db.products.createIndex( { "product_attributes.$**" : 1 } )
通配符索引可以支持任意单字段查询 product_attributes或其嵌入字段
db.products.find( { "product_attributes.size.length" : { $gt : 60 } } )
db.products.find( { "product_attributes.material" : "Leather" } )
db.products.find( { "product_attributes.secret_feature.name" : "laser" })
注意事项 : 通配符索引不兼容的索引类型或属性
#通配符索引不能支持以下查询
db.products.find({
"product_attributes": {
$exists: false
}
})
db.products.aggregate([{
$match: {
"product_attributes": {
$exists: false
}
}
}])
#通配符索引不能支持以下查询:
db.products.find({ "product_attributes.colors" : [ "Blue", "Black" ] } )
db.products.aggregate([{
$match : { "product_attributes.colors" : [ "Blue", "Black" ] }
}])
索引属性
唯一索引(Unique Indexes)
部分索引(Partial Indexes)
db.restaurants.createIndex(
{ cuisine: 1, name: 1 },
{ partialFilterExpression: { rating: { $gt: 5 } } }
)
# 符合条件,使用索引
db.restaurants.find( { cuisine: "Italian", rating: { $gte: 8 } } )
# 不符合条件,不能使用索引
db.restaurants.find( { cuisine: "Italian" } )
稀疏索引(Sparse Indexes)
#不索引不包含xmpp_id字段的文档
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
TTL索引(TTL Indexes)
db.log_events.insertOne( {
"createdAt": new Date(),
"logEvent": 2,
"logMessage": "Success!"
} )
db.log_events.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 20 })
最后被清理掉了,并没有查询到数据
索引使用建议
1.为每一个查询建立合适的索引
2.创建合适的复合索引,不要依赖于交叉索引
3.复合索引字段顺序:匹配条件在前,范围条件在后(Equality First, Range After)
4.尽可能使用覆盖索引(Covered Index)
5.建索引要在后台运行
6.避免设计过长的数组索引
explain执行计划详解
db.collection.find().explain(<verbose>)
模式名字 |
描述 |
queryPlanner |
执行计划的详细信息 ,包括查询计划、集合信息、查询条件、最佳执行划、查询方式和 MongoDB 服务信息等 |
exectionStats |
最佳执行计划的执行情况和被拒绝的计划等信息 |
allPlansExecution |
选择并执行最佳执行计划 ,并返回最佳执行计划和其他执行计划的执行情 况 |
# 未创建title的索引
db.books.find({title:"book‐1"}).explain("queryPlanner")
字段名称 |
描述 |
plannerVersion |
执行计划的版本 |
namespace |
查询的集合 |
indexFilterSet |
是否使用索引 |
parsedQuery |
查询条件 |
winningPlan |
最佳执行计划 |
stage |
查询方式 |
filter |
过滤条件 |
direction |
查询顺序 |
rejectedPlans |
拒绝的执行计划 |
serverInfo |
mongodb服务器信息 |
executionStats
#创建索引
db.books.createIndex({title:1})
db.books.find({title:"book‐1"}).explain("executionStats")
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.books.find({title:"book‐1"}).explain("executionStats")
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "restaurant.books",
"indexFilterSet" : false,
"parsedQuery" : {
"title" : {
"$eq" : "book‐1"
}
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"title" : 1
},
"indexName" : "title_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"title" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"title" : [
"[\"book‐1\", \"book‐1\"]"
]
}
}
},
"rejectedPlans" : [ ]
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 0,
"totalKeysExamined" : 0,
"totalDocsExamined" : 0,
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"keyPattern" : {
"title" : 1
},
"indexName" : "title_1",
"isMultiKey" : false,
"multiKeyPaths" : {
"title" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"title" : [
"[\"book‐1\", \"book‐1\"]"
]
},
"keysExamined" : 0,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
}
}
},
"serverInfo" : {
"host" : "192.168.30.130",
"port" : 27017,
"version" : "4.4.9",
"gitVersion" : "b4048e19814bfebac717cf5a880076aa69aba481"
},
"ok" : 1
}
字段名称 |
描述 |
winningPlan.inputStage |
用来描述子stage ,并且为其父stage提供文档和 索引关键字 |
winningPlan.inputStage.stage |
子查询方式 |
winningPlan.inputStage.keyPattern |
所扫描的index内容 |
winningPlan.inputStage.indexName |
索引名 |
winningPlan.inputStage.isMultiKey |
是否是Multikey。如果索引建立在array上 ,将是 true |
executionStats.executionSuccess |
是否执行成功 |
executionStats.nReturned |
返回的个数 |
executionStats.executionTimeMillis |
这条语句执行时间 |
executionStats.executionStages.executionTim eMillisEstimate |
检索文档获取数据的时间 |
executionStats.executionStages.inputStage.ex ecutionTimeMillisEstimate |
扫描获取数据的时间 |
executionStats.totalKeysExamined |
索引扫描次数 |
executionStats.totalDocsExamined |
文档扫描次数 |
executionStats.executionStages.isEOF |
是否到达 steam 结尾, 1 或者 true 代表已到达结 尾 |
executionStats.executionStages.works |
工作单元数 ,一个查询会分解成小的工作单元 |
executionStats.executionStages.advanced |
优先返回的结果数 |
executionStats.executionStages.docsExamine |
文档检查数 |
状态 |
描述 |
COLLSCAN |
全表扫描 |
IXSCAN |
索引扫描 |
FETCH |
根据索引检索指定文档 |
SHARD_MERGE |
将各个分片返回数据进行合并 |
SORT |
在内存中进行了排序 |
LIMIT |
使用limit限制返回数 |
SKIP |
使用skip进行跳过 |
IDHACK |
对_id进行查询 |
SHARDING_FILTER |
通过mongos对分片数据进行查询 |
COUNTSCAN |
count不使用Index进行count时的stage返回 |
COUNT_SCAN |
count使用了Index进行count时的stage返回 |
SUBPLA |
未使用到索引的$or查询的stage返回 |
TEXT |
使用全文索引进行查询时候的stage返回 |
PROJECTION文章来源:https://www.toymoban.com/news/detail-492587.html |
限定返回字段时候stage的返回文章来源地址https://www.toymoban.com/news/detail-492587.html |
到了这里,关于MongoDB索引详解-03的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!