首页 > 其他分享 >monodb4.4 index《一》

monodb4.4 index《一》

时间:2023-04-05 10:09:09浏览次数:41  
标签:username index false wang age monodb4.4 nReturned stage

1.索引简介

(1).准备基础数据
for (i=0;i<1000000; i++){
  db.users.insertOne({"i":i,username:"user"+i,age:Math.floor(Math.random()*120),created:new Date()})
}
(2).然后随机查找一个用户
wang> db.users.find({"username": "user101"}).explain("executionStats")
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "wang.users",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "username" : {
                                "$eq" : "user101"
                        }
                },
                "winningPlan" : {
                        "stage" : "COLLSCAN",
                        "filter" : {
                                "username" : {
                                        "$eq" : "user101"
                                }
                        },
                        "direction" : "forward"
                },
                "rejectedPlans" : [ ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 1,
                "executionTimeMillis" : 848,
                "totalKeysExamined" : 0,
                "totalDocsExamined" : 1000000,
                "executionStages" : {
                        "stage" : "COLLSCAN",
                        "filter" : {
                                "username" : {
                                        "$eq" : "user101"
                                }
                        },
                        "nReturned" : 1,
                        "executionTimeMillisEstimate" : 106,
                        "works" : 1000002,
                        "advanced" : 1,
                        "needTime" : 1000000,
                        "needYield" : 0,
                        "saveState" : 1000,
                        "restoreState" : 1000,
                        "isEOF" : 1,
                        "direction" : "forward",
                        "docsExamined" : 1000000
                }
        },
        "serverInfo" : {
                "host" : "localhost.localdomain",
                "port" : 27017,
                "version" : "4.4.0",
                "gitVersion" : "563487e100c4215e2dce98d0af2a6a5a2d67c5cf"
        },
        "ok" : 1
}
wang> 

其中重点关注executionStats的以下参数

totalDocsExamined   已扫描的文档总数
executionTimeMillis 执行该操作所需的毫秒数
nReturned           返回的文档数
totalKeysExamined   显示0表示此查询未使用索引
(3).创建索引
db.users.createIndex({"username" : 1})

如果要查询索引的创建进度,可以使用以下命令

db.currentOp()

此时再次进行上面的查询(关注标红部分,增加索引后性能提升很大):

wang> db.users.find({"username": "user101"}).explain("executionStats")
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "wang.users",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "username" : {
                                "$eq" : "user101"
                        }
                },
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "username" : 1
                                },
                                "indexName" : "username_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "username" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "username" : [
                                                "[\"user101\", \"user101\"]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 1,
                "executionTimeMillis" : 57,
                "totalKeysExamined" : 1,
                "totalDocsExamined" : 1,
                "executionStages" : {
                        "stage" : "FETCH",
                        "nReturned" : 1,
                        "executionTimeMillisEstimate" : 10,
                        "works" : 2,
                        "advanced" : 1,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "docsExamined" : 1,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 1,
                                "executionTimeMillisEstimate" : 10,
                                "works" : 2,
                                "advanced" : 1,
                                "needTime" : 0,
                                "needYield" : 0,
                                "saveState" : 0,
                                "restoreState" : 0,
                                "isEOF" : 1,
                                "keyPattern" : {
                                        "username" : 1
                                },
                                "indexName" : "username_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "username" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "username" : [
                                                "[\"user101\", \"user101\"]"
                                        ]
                                },
                                "keysExamined" : 1,
                                "seeks" : 1,
                                "dupsTested" : 0,
                                "dupsDropped" : 0
                        }
                }
        },
        "serverInfo" : {
                "host" : "localhost.localdomain",
                "port" : 27017,
                "version" : "4.4.0",
                "gitVersion" : "563487e100c4215e2dce98d0af2a6a5a2d67c5cf"
        },
        "ok" : 1
}
wang> 

2.复合索引(Compound Indexes)

复合索引就是建立在一个或多个字段上的索引

db.users.createIndex({"age" : 1, "username" : 1})

mongodb对这个索引的使用方式取决于查询的类型,下面是三种主要的方式。

(1).方式一
db.users.find({age:21}).sort({username:-1})

这个查询中第一个字段是等值查询,第二个字段已经在索引中了,查询结果已经是有序的了,所以逆序便利索引即可,查看执行计划

wang> db.users.find({age:21}).sort({username:-1}).explain("executionStats")
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "wang.users",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "age" : {
                                "$eq" : 21
                        }
                },
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "age" : 1,
                                        "username" : 1
                                },
                                "indexName" : "age_1_username_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "age" : [ ],
                                        "username" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "backward",
                                "indexBounds" : {
                                        "age" : [
                                                "[21.0, 21.0]"
                                        ],
                                        "username" : [
                                                "[MaxKey, MinKey]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 8336,
                "executionTimeMillis" : 47,
                "totalKeysExamined" : 8336,
                "totalDocsExamined" : 8336,
                "executionStages" : {
                        "stage" : "FETCH",
                        "nReturned" : 8336,
                        "executionTimeMillisEstimate" : 14,
                        "works" : 8337,
                        "advanced" : 8336,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 8,
                        "restoreState" : 8,
                        "isEOF" : 1,
                        "docsExamined" : 8336,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 8336,
                                "executionTimeMillisEstimate" : 0,
                                "works" : 8337,
                                "advanced" : 8336,
                                "needTime" : 0,
                                "needYield" : 0,
                                "saveState" : 8,
                                "restoreState" : 8,
                                "isEOF" : 1,
                                "keyPattern" : {
                                        "age" : 1,
                                        "username" : 1
                                },
                                "indexName" : "age_1_username_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "age" : [ ],
                                        "username" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "backward",
                                "indexBounds" : {
                                        "age" : [
                                                "[21.0, 21.0]"
                                        ],
                                        "username" : [
                                                "[MaxKey, MinKey]"
                                        ]
                                },
                                "keysExamined" : 8336,
                                "seeks" : 1,
                                "dupsTested" : 0,
                                "dupsDropped" : 0
                        }
                }
        },
        "serverInfo" : {
                "host" : "localhost.localdomain",
                "port" : 27017,
                "version" : "4.4.0",
                "gitVersion" : "563487e100c4215e2dce98d0af2a6a5a2d67c5cf"
        },
        "ok" : 1
}
wang> 

这种查询是非常高效的,mongodb能够直接定位到正确的年龄,而且不需要对结果进行排序(因为只需要对数据进行逆序遍历就可以得到正确的顺序了)。

注意。排序的方向并不重要,mongodb可以在任意方向上对索引进行遍历。

(2).方式二
db.users.find({"age" : {"$gte" : 21, "$lte" : 30}})

这是一个多值查询,用于查找匹配多个值的文档(在此情况下,年龄在21至30岁之间)。 这种特定类型的查询有时也称为范围查询。 MongoDB将使用索引中的第一个键age返回匹配的文档

wang> db.users.find({"age" : {"$gte" : 21, "$lte" : 30}}).explain("executionStats")
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "wang.users",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "$and" : [
                                {
                                        "age" : {
                                                "$lte" : 30
                                        }
                                },
                                {
                                        "age" : {
                                                "$gte" : 21
                                        }
                                }
                        ]
                },
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "age" : 1,
                                        "username" : 1
                                },
                                "indexName" : "age_1_username_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "age" : [ ],
                                        "username" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "age" : [
                                                "[21.0, 30.0]"
                                        ],
                                        "username" : [
                                                "[MinKey, MaxKey]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 83522,
                "executionTimeMillis" : 333,
                "totalKeysExamined" : 83522,
                "totalDocsExamined" : 83522,
                "executionStages" : {
                        "stage" : "FETCH",
                        "nReturned" : 83522,
                        "executionTimeMillisEstimate" : 73,
                        "works" : 83523,
                        "advanced" : 83522,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 83,
                        "restoreState" : 83,
                        "isEOF" : 1,
                        "docsExamined" : 83522,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 83522,
                                "executionTimeMillisEstimate" : 32,
                                "works" : 83523,
                                "advanced" : 83522,
                                "needTime" : 0,
                                "needYield" : 0,
                                "saveState" : 83,
                                "restoreState" : 83,
                                "isEOF" : 1,
                                "keyPattern" : {
                                        "age" : 1,
                                        "username" : 1
                                },
                                "indexName" : "age_1_username_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "age" : [ ],
                                        "username" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "age" : [
                                                "[21.0, 30.0]"
                                        ],
                                        "username" : [
                                                "[MinKey, MaxKey]"
                                        ]
                                },
                                "keysExamined" : 83522,
                                "seeks" : 1,
                                "dupsTested" : 0,
                                "dupsDropped" : 0
                        }
                }
        },
        "serverInfo" : {
                "host" : "localhost.localdomain",
                "port" : 27017,
                "version" : "4.4.0",
                "gitVersion" : "563487e100c4215e2dce98d0af2a6a5a2d67c5cf"
        },
        "ok" : 1
}
wang> 
(3).方式三
db.users.find({"age" : {"$gte" : 21, "$lte" :30}}).sort({"username" : 1})

由于第一个字段使用了范围查询,所以第二哥字段无法使用索引,所以必须在内存中进行排序,因此这种查询不如第一个高效

wang> db.users.find({"age" : {"$gte" : 21, "$lte" :30}}).sort({"username" : 1}).explain("executionStats")
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "wang.users",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "$and" : [
                                {
                                        "age" : {
                                                "$lte" : 30
                                        }
                                },
                                {
                                        "age" : {
                                                "$gte" : 21
                                        }
                                }
                        ]
                },
                "winningPlan" : {
                        "stage" : "FETCH",
                        "filter" : {
                                "$and" : [
                                        {
                                                "age" : {
                                                        "$lte" : 30
                                                }
                                        },
                                        {
                                                "age" : {
                                                        "$gte" : 21
                                                }
                                        }
                                ]
                        },
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "username" : 1
                                },
                                "indexName" : "username_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "username" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "username" : [
                                                "[MinKey, MaxKey]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [
                        {
                                "stage" : "FETCH",
                                "inputStage" : {
                                        "stage" : "SORT",
                                        "sortPattern" : {
                                                "username" : 1
                                        },
                                        "memLimit" : 104857600,
                                        "type" : "default",
                                        "inputStage" : {
                                                "stage" : "IXSCAN",
                                                "keyPattern" : {
                                                        "age" : 1,
                                                        "username" : 1
                                                },
                                                "indexName" : "age_1_username_1",
                                                "isMultiKey" : false,
                                                "multiKeyPaths" : {
                                                        "age" : [ ],
                                                        "username" : [ ]
                                                },
                                                "isUnique" : false,
                                                "isSparse" : false,
                                                "isPartial" : false,
                                                "indexVersion" : 2,
                                                "direction" : "forward",
                                                "indexBounds" : {
                                                        "age" : [
                                                                "[21.0, 30.0]"
                                                        ],
                                                        "username" : [
                                                                "[MinKey, MaxKey]"
                                                        ]
                                                }
                                        }
                                }
                        }
                ]
        },
        "executionStats" : {
                "executionSuccess" : true,
                "nReturned" : 83522,
                "executionTimeMillis" : 3292,
                "totalKeysExamined" : 1000000,
                "totalDocsExamined" : 1000000,
                "executionStages" : {
                        "stage" : "FETCH",
                        "filter" : {
                                "$and" : [
                                        {
                                                "age" : {
                                                        "$lte" : 30
                                                }
                                        },
                                        {
                                                "age" : {
                                                        "$gte" : 21
                                                }
                                        }
                                ]
                        },
                        "nReturned" : 83522,
                        "executionTimeMillisEstimate" : 765,
                        "works" : 1000001,
                        "advanced" : 83522,
                        "needTime" : 916478,
                        "needYield" : 0,
                        "saveState" : 1001,
                        "restoreState" : 1001,
                        "isEOF" : 1,
                        "docsExamined" : 1000000,
                        "alreadyHasObj" : 0,
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "nReturned" : 1000000,
                                "executionTimeMillisEstimate" : 315,
                                "works" : 1000001,
                                "advanced" : 1000000,
                                "needTime" : 0,
                                "needYield" : 0,
                                "saveState" : 1001,
                                "restoreState" : 1001,
                                "isEOF" : 1,
                                "keyPattern" : {
                                        "username" : 1
                                },
                                "indexName" : "username_1",
                                "isMultiKey" : false,
                                "multiKeyPaths" : {
                                        "username" : [ ]
                                },
                                "isUnique" : false,
                                "isSparse" : false,
                                "isPartial" : false,
                                "indexVersion" : 2,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "username" : [
                                                "[MinKey, MaxKey]"
                                        ]
                                },
                                "keysExamined" : 1000000,
                                "seeks" : 1,
                                "dupsTested" : 0,
                                "dupsDropped" : 0
                        }
                }
        },
        "serverInfo" : {
                "host" : "localhost.localdomain",
                "port" : 27017,
                "version" : "4.4.0",
                "gitVersion" : "563487e100c4215e2dce98d0af2a6a5a2d67c5cf"
        },
        "ok" : 1
}
wang> 

如果您的结果超过32MB结果MongoDB只会出错,拒绝对大量数据进行排序:

Error: error: {
  "ok" : 0,
  "errmsg" : "Executor error during find command: OperationFailed:
Sort operation used more than the maximum 33554432 bytes of RAM. Add
an index, or specify a smaller limit.",
  "code" : 96,
  "codeName" : "OperationFailed"
}

如果使用 {"username" : 1, "age" : 1} 索引会得到很好的效果。

设计复合索引时:

等值查询的键应该首先出现。

用于排序的键应该出现在多值字段之前。

多值过滤器的键应该出现在最后。

标签:username,index,false,wang,age,monodb4.4,nReturned,stage
From: https://blog.51cto.com/u_13753753/6170221

相关文章

  • monodb4.4 index《二》
    1.使用复合索引(1).索引的方向2个字段都按照升序{"age":1,"username":1}age按照升序,username按照降序{"age":1,"username":-­1}以下2个索引是一样的{"age":1,"username":­-1}{"age":-­1,"username":1}(2).......
  • 存储IndexedDB之Dexie
    [前端大容量存储IndexedDB之Dexie.js-掘金](https://juejin.cn/post/7025592963002531871) IndexedDB存储Dexie.js 对IndexedDB的封装,语法简单,可以快速方便的编写代码 webSQL总结webSQL标准不再更新,关系型数据库,底层sqlitechrome中容量5M,支持同域名不同页面共享......
  • eyoucms 去掉 index.php后缀
    针对不同服务器、虚拟空间,运行PHP的环境也有所不同,目前主要分为:Nginx、apache、IIS以及其他服务器。下面分享如何去掉URL上的index.php字符,记得在管理后台清除缓存,对于一些ECS服务器可能要重启nginx等服务!【Nginx服务器】在原有的nginx重写文件里新增以下代码片段:location/......
  • VLOOKUP 、 INDEX 、MATCH
    VLOOKUP:VLOOKUP函数是Excel中的一个纵向查找函数,它与LOOKUP函数和HLOOKUP函数属于一类函数,在工作中都有广泛应用,例如可以用来核对数据,多个表格之间快速导入数据等函数功能。功能是按列查找,最终返回该列所需查询序列所对应的值;与之对应的HLOOKUP是按行查找的。 Vlookup最容易......
  • mysql Error:index column size too large. the maximum column size is 767 bytes
    问题现象mysql在执行脚本create创建表时,提示以下错误:indexcolumnsizetoolarge.themaximumcolumnsizeis767bytes异常原因INNODB引擎,UTF-8,主键字符串默认最大767,需要修改解决方案对数据库进行设置setglobalinnodb_large_prefix=ON参考博客......
  • mysql加解密,substring substring_index函数
    mysql加解密,substringsubstring_index函数SELECTto_base64(AES_ENCRYPT('测试串','key12345678'));SELECTAES_DECRYPT(from_base64('iqJIDwYLlcAZ/AP3VvODJg=='),'ke......
  • 在python的setup.py中如何指定多个extra-index-url?
    [本文出自天外归云的博客园]以下内容来自chatGPT的回答(正解,已验证)问题:在pythonsetup.py中如何指定多个extra-index-url?在`setup.py`文件中,我们可以使用`setuptools`......
  • Magento : Make 'Continue Shopping' button redirect to the product index page
    Magento:Make'ContinueShopping'buttonredirecttothelast-added-to-cartproduct'scategory Editcart.phtmlandreplacefollowingcode<?php......
  • How to use --extra-index-url in requirements.txt in python?
    [本文出自天外归云的博客园]以下内容来自chatGPT的回答(正解,已验证)问题1:howtouse--extra-index-urlinrequirements.txtinpython?Touse`--extra-index-url`in`......
  • python基础:split、join、replace、remove、del、pop、index小记python 字符串的split(
    这里总结了平时写脚本时经常用到的一些基础方法,做个记录1、split()函数可以基于分隔符将字符串分割成由若干子串组成的列表str.split(str="",num=string.count(str))str......