[211119] MongoDB#索引详解
索引的相关术语
什么是查询覆盖(covered query)?
:所需字段都在索引中,无需额外字段的,直接在索引表中就返回数据。
什么是索引扫描(IXSCAN)?
:扫描索引表。(性能更高)
什么是集合扫描(COLLSCAN)?
扫描整个集合。
什么是时间复杂度?
:
什么是查询形状(Query Shape)?
要查询的哪些字段。
什么是索引前缀(Index Prefix)?
什么是过滤性(Selectivity)
要选择过滤性最强的字段做索引,比如:
假设集合有1万条数据
a字段做索引,过滤得10条。
b字段做索引,过滤的4000条。
那么,若只许一个做索引,则优先a字段。
【记住】过滤性越强,越要优先考虑:
什么是B树结构(一种算法数据结构)?
索引背后是B-树。理解B-树,对正确使用索引有帮助。
什么是执行计划?
执行计划用于检查查询语句的性能,包括索引是否生效,查询扫表情况,执行耗时等。
比如,MongoDB的执行计划可通过 explain() 函数进行查看执行预期:
db.collection.explain().<method(...)>
// explain入参:"queryPlanner" (Default) | "executionStats" | "allPlansExecution"
索引的几种类型 *
单键索引、组合索引、多值索引、地理位置索引、全文索引、TTL索引、部分索引、哈希索引。
索引的设计原则(ESR)
设置组合索引的最佳方式:ESR原则 (必须按此顺序设计组合索引)
- 精确(Equal)匹配的字段放最前(考虑过滤性强不强)
- 排序(Sort)条件放中间
- 范围(Range)匹配的字段放最后
【说明】如果凑不齐ESR原则,ES、ER也可。
索引的基本操作
创建、查看、删除、看索引大小,参考这篇。
查看索引使用情况
db.文档名.aggregate( [ { $indexStats: { } }, { $sort: { name: 1 } } ] )
【例】使用 {#indexStats:{}}
查看 violation 的索引使用情况,重点关注 accesses.ops
即可,该字段能够说明每个索引的使用情况,。(👉🏻 详解 $indexStats):
db.violation.aggregate([{
$indexStats: {}
}, {
$sort: {
name: 1
}
}])
结果:
// 1
{
"name": "_id_",
"key": {
"_id": NumberInt("1")
},
"host": "a4718a113fc2:27017",
"accesses": {
// 从2021年11月10日 13:37:41到现在,当前索引生效了5千万次左右
"ops": NumberLong("59562398"),
"since": ISODate("2021-11-10T05:37:41.52Z")
},
"spec": {
"v": NumberInt("2"),
"key": {
"_id": NumberInt("1")
},
"name": "_id_",
"ns": "governance-center.violation"
}
}
// 2
{
"name": "compound_index_desc",
"key": {
"carNumCol": NumberInt("-1"),
"startTime": NumberInt("-1"),
"workOrderId": NumberInt("1"),
"violationTypeNo": NumberInt("-1"),
"companyId": NumberInt("-1"),
"organizationId": NumberInt("-1"),
"violationStatusPriority": NumberInt("1")
},
"host": "a4718a113fc2:27017",
"accesses": {
"ops": NumberLong("328634"),
"since": ISODate("2021-11-10T05:37:41.52Z")
},
"spec": {
"v": NumberInt("2"),
"key": {
"carNumCol": NumberInt("-1"),
"startTime": NumberInt("-1"),
"workOrderId": NumberInt("1"),
"violationTypeNo": NumberInt("-1"),
"companyId": NumberInt("-1"),
"organizationId": NumberInt("-1"),
"violationStatusPriority": NumberInt("1")
},
"name": "compound_index_desc",
"ns": "governance-center.violation"
}
}
// 3
{
"name": "compound_index_page",
"key": {
"startTime": NumberInt("-1"),
"violationStatusPriority": NumberInt("1")
},
"host": "a4718a113fc2:27017",
"accesses": {
"ops": NumberLong("1098"),
"since": ISODate("2021-11-10T05:37:41.52Z")
},
"spec": {
"v": NumberInt("2"),
"key": {
"startTime": NumberInt("-1"),
"violationStatusPriority": NumberInt("1")
},
"name": "compound_index_page",
"ns": "governance-center.violation"
}
}
// 4
{
"name": "flagStatus_desc",
"key": {
"flagStatus": NumberInt("-1")
},
"host": "a4718a113fc2:27017",
"accesses": {
"ops": NumberLong("234"),
"since": ISODate("2021-11-10T05:37:41.52Z")
},
"spec": {
"v": NumberInt("2"),
"key": {
"flagStatus": NumberInt("-1")
},
"name": "flagStatus_desc",
"ns": "governance-center.violation"
}
}
// 5
{
"name": "operationType_desc",
"key": {
"operationType": NumberInt("-1")
},
"host": "a4718a113fc2:27017",
"accesses": {
"ops": NumberLong("0"),
"since": ISODate("2021-11-10T05:37:41.52Z")
},
"spec": {
"v": NumberInt("2"),
"key": {
"operationType": NumberInt("-1")
},
"name": "operationType_desc",
"ns": "governance-center.violation"
}
}
// 6
{
"name": "startTime",
"key": {
"startTime": NumberInt("-1")
},
"host": "a4718a113fc2:27017",
"accesses": {
"ops": NumberLong("408494"),
"since": ISODate("2021-11-10T05:37:41.52Z")
},
"spec": {
"v": NumberInt("2"),
"key": {
"startTime": NumberInt("-1")
},
"name": "startTime",
"ns": "governance-center.violation"
}
}
// 7
{
"name": "tradeType_desc",
"key": {
"tradeType": NumberInt("-1")
},
"host": "a4718a113fc2:27017",
"accesses": {
"ops": NumberLong("0"),
"since": ISODate("2021-11-10T05:37:41.52Z")
},
"spec": {
"v": NumberInt("2"),
"key": {
"tradeType": NumberInt("-1")
},
"name": "tradeType_desc",
"ns": "governance-center.violation"
}
}
// 8
{
"name": "violationType_desc",
"key": {
"violationType": NumberInt("-1")
},
"host": "a4718a113fc2:27017",
"accesses": {
"ops": NumberLong("11"),
"since": ISODate("2021-11-10T05:37:41.52Z")
},
"spec": {
"v": NumberInt("2"),
"key": {
"violationType": NumberInt("-1")
},
"name": "violationType_desc",
"ns": "governance-center.violation"
}
}
不当操作对索引的影响 *
$group对索引的影响
$nin对索引的影响
$nin
会发起全表扫描,因此,建议使用$ne
替代 $nin
。
$regex对索引的影响
可以使用前缀表达式可以触发索引。
$or对索引的影响
必须为$or
中所有的字段建立索引,否则$or
将使索引失效