MongoDB索引

- MongoDB索引注意事项:

  1. MongoDB的索引是存储在运行内存(RAM)中的,所以必须确保索引的大小不超过内存的限制。

    如果索引的大小超过了运行内存的限制,MongoDB会删除一些索引,这将导致性能下降。

  2. MongoDB的索引在部分查询条件下是不会生效的。

    • 正则表达式及非操作符,如 $nin,$not , 等。

    • 算术运算符,如 $mod, 等。

    • $where自定义查询函数。

    • ...

  3. 索引会在写入数据(添加、更新和删除)时重排,如果项目如果是写多读少,则建议少使用或者不要使用索引。

  4. 一个集合中索引数量不能超过64个。

  5. 索引名的长度不能超过128个字符。

  6. 一个复合索引最多可以有31个字段。

  7. mongodb索引统一在system.indexes集合中管理。这个集合只能通过createIndexdropIndexes来操作。

// 获取当前集合中已经创建的所有索引信息
db.集合.getIndexes()
/*
[{
"v" : 2, // 索引版本
"key" : { // 索引的字段及排序方向(1表示升序,-1表示降序)
"_id" : 1 // 根据_id字段升序索引
},
"name" : "_id" // 索引的名称
}]
*/
// 获取当前集合中已经创建的索引总大小,以字节为单位返回结果
db.集合.totalIndexSize()
// 获取当前数据库中所有的索引【不会显示_id主键】
db.system.indexes.find()

 

MongoDB默认会为插入的文档生成_id字段(如果应用本身没有指定该字段),_id是文档唯一的标识,为了保证能根据文档id快递查询文档,MongoDB默认会为集合创建_id字段的主键索引。

查询分析

与SQL语句类似,MongoDB也提供了一个explain,供开发者进行查询分析。

explain的使用有3个参数,分别是:queryPlanner、executionStats、allPlansExecution,默认是queryPlanner,开发中常用的是executionStats。

db.orders.find({"title":"购买商品-19"}).explain("executionStats")
/*
{
    "queryPlanner" : {  # 被查询优化器选择出来的查询计划
        "plannerVersion" : 1,  # 查询计划版本
        "namespace" : "test.orders", # 要查询的集合
        "indexFilterSet" : false,  # 是否了使用索引
        "parsedQuery" : {  # 查询条件
            "title" : {
                "$eq" : "购买商品-19"
            }
        },
        "winningPlan" : {     # 最佳执行计划
            "stage" : "COLLSCAN", # 扫描类型/扫描阶段
            "filter" : {     # 过滤条件
                "title" : {
                    "$eq" : "购买商品-19"
                }
            },
            "direction" : "forward"  # 查询方向,forward为升序,backward表示倒序。
        },
        "rejectedPlans" : [ ]   # 拒绝的执行计划
    },
    "executionStats" : {  # 最佳执行计划的一些统计信息
        "executionSuccess" : true,  # 是否执行成功
        "nReturned" : 1,   # 返回的结果数
        "executionTimeMillis" : 346,  # 执行耗时
        "totalKeysExamined" : 0,      # 索引扫描次数
        "totalDocsExamined" : 1000000,  # 文档扫描次数,所谓的优化无非是让totalDocsExamined和nReturned的值接近。
        "executionStages" : {     # 执行状态
            "stage" : "COLLSCAN",  # 扫描方式/扫描阶段
            "filter" : {
                "title" : {
                    "$eq" : "购买商品-19"
                }
            },
            "nReturned" : 1,   # 返回的结果数
            "executionTimeMillisEstimate" : 5,   # 预估耗时
            "works" : 1000002,   # 工作单元数
            "advanced" : 1,      # 优先返回的结果数
            "needTime" : 1000000,
            "needYield" : 0,
            "saveState" : 1000,
            "restoreState" : 1000,
            "isEOF" : 1,
            "direction" : "forward",
            "docsExamined" : 1000000   # 文档检查数目,与totalDocsExamined一致
        }
    },
    "serverInfo" : {   # 服务器信息
        "host" : "ubuntu",
        "port" : 27017,
        "version" : "4.4.2",
        "gitVersion" : "15e73dc5738d2278b688f8929aee605fe4279b0e"
    },
    "ok" : 1
}

*/

stage的扫描类型:

类型名称描述期望
COLLSCAN 全表扫描 False
IXSCAN 索引扫描 True
FETCH 根据索引去检索指定document True
IDHACK 针对_id进行查询 True
COUNTSCAN count不使用Index进行count时返回 False
COUNT_SCAN count使用了Index进行count时返回 True
SUBPLA 未使用到索引的$or查询时返回 False
TEXT 使用全文索引进行查询时返回 -
SORT 使用sort排序但是无index时返回 False
SKIP 使用skip跳过但是无index时返回 False
PROJECTION 使用limit限定结果但是无index时返回 False

 

创建索引

MongoDB支持多种类型的索引,包括普通索引、复合索引、多列索引、全文索引、哈希索引地理位置索引等,每种类型的索引有不同的使用场合。ttl索引本质上就是普通索引。另外,MongoDB的全文索引很弱智,如果真要用在开发中,还是建议使用elasticsearch或者Sphinx。

 

posted @ 2021-11-30 17:00  urls  阅读(477)  评论(0编辑  收藏  举报