iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >MongoDB中什么情况下索引会选择策略
  • 486
分享到

MongoDB中什么情况下索引会选择策略

2023-06-29 00:06:21 486人浏览 安东尼
摘要

这篇“MongoDB中什么情况下索引会选择策略”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“mongoDB中什么情况下索引会

这篇“MongoDB中什么情况下索引会选择策略”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“mongoDB中什么情况下索引会选择策略”文章吧。

一、MonGoDB如何选择索引

如果我们在Collection建了5个index,那么当我们查询的时候,MongoDB会根据查询语句的筛选条件、sort排序等来定位可以使用的index作为候选索引;然后MongoDB会创建对应数量的查询计划,并分别使用不同线程执行查询计划,最终会选择一个执行最快的index;但是这个选择也不是一成不变的,后续还会有一段时间根据实际执行情况动态调整;

MongoDB中什么情况下索引会选择策略

二、数据准备

for(let i = 0;i<1000000;i++){    db.users.insertOne({        "id":i,        "name":'user'+i,        "age":Math.floor(Math.random()*120),        "created":new Date(ISODate().getTime() - 1000 * 60*i)    });}

三、正则对index的使用

MongoDB支持正则查询,在特定的情况其也是可以利用index获得查询性能的提升;

虽然MongDB执行正则会最大限度的使用index,但是不同的用法还是会影响对index的利用程度的;

执行以下普通正则表达式

从queryPlanner.winningPlan部分的COLLSCAN,可以看到正则表达式默认会进行全表的扫描;

从executionStats.executionStages部分可以看到COLLSCAN共扫描了1000000个文档,并返回1111个文档,总耗时794ms;

db.users.find({    name:/user999/    }).explain('executionStats')    {    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,                "winningPlan" : {            "stage" : "COLLSCAN",            "filter" : {                "name" : {                    "$regex" : "user999"                }            },            "direction" : "forward"        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 1111,        "executionTimeMillis" : 909,        "totalKeysExamined" : 0,        "totalDocsExamined" : 1000000,        "executionStages" : {            "stage" : "COLLSCAN",            "filter" : {                "name" : {                    "$regex" : "user999"                }            },            "nReturned" : 1111,            "executionTimeMillisEstimate" : 794,            "works" : 1000002,            "advanced" : 1111,            "needTime" : 998890,            "needYield" : 0,            "saveState" : 7830,            "restoreState" : 7830,            "isEOF" : 1,            "invalidates" : 0,            "direction" : "forward",            "docsExamined" : 1000000        }    }}

创建一个包含name的index;

db.users.createIndex({name:1})

再次执行上边的查询,可以看到使用了我们新建的name_1索引;但是从执行状态来看,还是扫描了全体的索引的key,并不能很好的利用index;

{    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {            "name" : {                "$regex" : "user999"            }        },        "winningPlan" : {            "stage" : "FETCH",            "inputStage" : {                "stage" : "IXSCAN",                "filter" : {                    "name" : {                        "$regex" : "user999"                    }                },                "keyPattern" : {                    "name" : 1                },                "indexName" : "name_1"                            }        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 1111,        "executionTimeMillis" : 971,        "totalKeysExamined" : 1000000,        "totalDocsExamined" : 1111,        "executionStages" : {            "stage" : "FETCH",            "nReturned" : 1111,            "executionTimeMillisEstimate" : 887,                        "docsExamined" : 1111,            "alreadyHasObj" : 0,            "inputStage" : {                "stage" : "IXSCAN",                "filter" : {                    "name" : {                        "$regex" : "user999"                    }                },                "nReturned" : 1111,                "executionTimeMillisEstimate" : 876,                              "keyPattern" : {                    "name" : 1                },                "indexName" : "name_1",                              "keysExamined" : 1000000            }        }    }}

使用前缀匹配的话可以最大限度的利用index,从执行状态可以看到只检测了1111个index key;

db.users.find({    name:/^user999/    }).explain('executionStats')    {    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {            "name" : {                "$regex" : "^user999"            }        },        "winningPlan" : {            "stage" : "FETCH",            "inputStage" : {                "stage" : "IXSCAN",                "keyPattern" : {                    "name" : 1                },                "indexName" : "name_1"                            }        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 1111,        "executionTimeMillis" : 2,        "totalKeysExamined" : 1111,        "totalDocsExamined" : 1111,        "executionStages" : {            "stage" : "FETCH",            "nReturned" : 1111,            "executionTimeMillisEstimate" : 0            "docsExamined" : 1111                        "inputStage" : {                "stage" : "IXSCAN",                "nReturned" : 1111,                "executionTimeMillisEstimate" : 0,                "indexName" : "name_1",                "keysExamined" : 1111            }        }    }}

即使是前缀匹配,如果忽略大小写的话也无法充分利用index了;

db.users.find({    name:/^user999/i    }).explain('executionStats')    {    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {            "name" : {                "$regex" : "user999",                "$options" : "i"            }        },        "winningPlan" : {            "stage" : "FETCH",            "inputStage" : {                "stage" : "IXSCAN",                "filter" : {                    "name" : {                        "$regex" : "user999",                        "$options" : "i"                    }                },                "keyPattern" : {                    "name" : 1                },                "indexName" : "name_1"            }        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 1111,        "executionTimeMillis" : 943,        "totalKeysExamined" : 1000000,        "totalDocsExamined" : 1111,        "executionStages" : {            "stage" : "FETCH",            "nReturned" : 1111,            "executionTimeMillisEstimate" : 833,            "works" : 1000001,            "inputStage" : {                "stage" : "IXSCAN",                "filter" : {                    "name" : {                        "$regex" : "user999",                        "$options" : "i"                    }                },                "nReturned" : 1111,                "executionTimeMillisEstimate" : 833,                "keyPattern" : {                    "name" : 1                },                "indexName" : "name_1"                "keysExamined" : 1000000            }        }    }}

四、$or从句对索引的利用

MongoDB执行$or从句的时候,会将所有的从句作为逻辑的整体,要不就都使用index,要不就都进行全表扫描;

执行以下的查询语句;

db.users.find({    $or:[        {name:/^user666/},        {age:{$gte:80}}    ]    }).explain('executionStats')

在只有name_1这个index的时候,我们可以看到MongoDB进行了全表扫描,全表扫描的时候进行$or从句的过滤;

{    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {            "$or" : [                {                    "age" : {                        "$gte" : 20                    }                },                {                    "name" : {                        "$regex" : "^user666"                    }                }            ]        },        "winningPlan" : {            "stage" : "SUBPLAN",            "inputStage" : {                "stage" : "COLLSCAN",                "filter" : {                    "$or" : [                        {                            "age" : {                                "$gte" : 20                            }                        },                        {                            "name" : {                                "$regex" : "^user666"                            }                        }                    ]                },                "direction" : "forward"            }        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 833995,        "executionTimeMillis" : 576,        "totalKeysExamined" : 0,        "totalDocsExamined" : 1000000,        "executionStages" : {            "stage" : "SUBPLAN",            "nReturned" : 833995,            "executionTimeMillisEstimate" : 447,                       "inputStage" : {                "stage" : "COLLSCAN",                "filter" : {                    "$or" : [                        {                            "age" : {                                "$gte" : 20                            }                        },                        {                            "name" : {                                "$regex" : "^user666"                            }                        }                    ]                },                "nReturned" : 833995,                "executionTimeMillisEstimate" : 447,                               "docsExamined" : 1000000            }        }    }}

我们对name字段新建一个index;

db.users.createIndex({age:1})

再次执行以上的查询语句,这次可以看到每个从句都利用了index,并且每个从句会单独执行并最终进行or操作;

{    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {            "$or" : [                {                    "age" : {                        "$gte" : 80                    }                },                {                    "name" : {                        "$regex" : "^user666"                    }                }            ]        },        "winningPlan" : {            "stage" : "SUBPLAN",            "inputStage" : {                "stage" : "FETCH",                "inputStage" : {                    "stage" : "OR",                    "inputStages" : [                        {                            "stage" : "IXSCAN",                            "keyPattern" : {                                "name" : 1                            },                            "indexName" : "name_1",                            "isMultiKey" : false,                            "multiKeyPaths" : {                                "name" : [ ]                            },                            "isUnique" : false,                            "isSparse" : false,                            "isPartial" : false,                            "indexVersion" : 2,                            "direction" : "forward",                            "indexBounds" : {                                "name" : [                                    "[\"user666\", \"user667\")",                                    "[/^user666/, /^user666/]"                                ]                            }                        },                        {                            "stage" : "IXSCAN",                            "keyPattern" : {                                "age" : 1                            },                            "indexName" : "age_1",                            "isMultiKey" : false,                            "multiKeyPaths" : {                                "age" : [ ]                            },                            "isUnique" : false,                            "isSparse" : false,                            "isPartial" : false,                            "indexVersion" : 2,                            "direction" : "forward",                            "indexBounds" : {                                "age" : [                                    "[80.0, inf.0]"                                ]                            }                        }                    ]                }            }        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 333736,        "executionTimeMillis" : 741,        "totalKeysExamined" : 334102,        "totalDocsExamined" : 333736,        "executionStages" : {            "stage" : "SUBPLAN",            "nReturned" : 333736,            "executionTimeMillisEstimate" : 703,            "inputStage" : {                "stage" : "FETCH",                "nReturned" : 333736,                "executionTimeMillisEstimate" : 682                "docsExamined" : 333736,                                "inputStage" : {                    "stage" : "OR",                    "nReturned" : 333736,                    "executionTimeMillisEstimate" : 366,                    "inputStages" : [                        {                            "stage" : "IXSCAN",                            "nReturned" : 1111,                            "executionTimeMillisEstimate" : 0,                            "keyPattern" : {                                "name" : 1                            },                            "indexName" : "name_1",                            "indexBounds" : {                                "name" : [                                    "[\"user666\", \"user667\")",                                    "[/^user666/, /^user666/]"                                ]                            },                            "keysExamined" : 1112                        },                        {                            "stage" : "IXSCAN",                            "nReturned" : 332990,                            "executionTimeMillisEstimate" : 212,                                                      "keyPattern" : {                                "age" : 1                            },                            "indexName" : "age_1",                                                       "indexBounds" : {                                "age" : [                                    "[80.0, inf.0]"                                ]                            },                            "keysExamined" : 332990                        }                    ]                }            }        }    }}

五、sort对索引的利用

如果sort操作无法利用index,则MongoDB就会在内存中排序数据,并且数据量一大就会报错;

db.users.find().sort({created: -1}).explain('executionStats'){    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {                    },        "winningPlan" : {            "stage" : "SORT",            "sortPattern" : {                "created" : -1            },            "inputStage" : {                "stage" : "SORT_KEY_GENERATOR",                "inputStage" : {                    "stage" : "COLLSCAN",                    "direction" : "forward"                }            }        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : false,        "errORMessage" : "Exec error resulting in state FAILURE :: caused by :: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.",        "errorCode" : 96,        "nReturned" : 0,        "executionTimeMillis" : 959,        "totalKeysExamined" : 0,        "totalDocsExamined" : 361996,        "executionStages" : {            "stage" : "SORT",            "nReturned" : 0,            "executionTimeMillisEstimate" : 922,            "sortPattern" : {                "created" : -1            },            "memUsage" : 33554518,            "memLimit" : 33554432,            "inputStage" : {                "stage" : "SORT_KEY_GENERATOR",                "nReturned" : 361996,                "executionTimeMillisEstimate" : 590,                "inputStage" : {                    "stage" : "COLLSCAN",                    "nReturned" : 361996,                    "executionTimeMillisEstimate" : 147,                    "direction" : "forward",                    "docsExamined" : 361996                }            }        }    }}

如果是单字段index,sort从两个方向都可以充分利用index;可以看到MongoDB直接按照index的顺序返回结果,直接就没有sort阶段了;

db.users.find().sort({name: -1}).explain('executionStats')      {    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {                    },        "winningPlan" : {            "stage" : "FETCH",            "inputStage" : {                "stage" : "IXSCAN",                "keyPattern" : {                    "name" : 1                },                "indexName" : "name_1",                "direction" : "backward",                "indexBounds" : {                    "name" : [                        "[MaxKey, MinKey]"                    ]                }            }        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 1000000,        "executionTimeMillis" : 1317,        "totalKeysExamined" : 1000000,        "totalDocsExamined" : 1000000,        "executionStages" : {            "stage" : "FETCH",            "nReturned" : 1000000,            "executionTimeMillisEstimate" : 1180,            "inputStage" : {                "stage" : "IXSCAN",                "nReturned" : 1000000,                "executionTimeMillisEstimate" : 560,                "keyPattern" : {                    "name" : 1                },                "indexName" : "name_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "name" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "backward",                "indexBounds" : {                    "name" : [                        "[MaxKey, MinKey]"                    ]                },                "keysExamined" : 1000000,                "seeks" : 1,                "dupsTested" : 0,                "dupsDropped" : 0,                "seenInvalidated" : 0            }        }    }}

对于复合索引,sort除了可以从整体上从两个方向利用index,也可以利用index的前缀索引和非前缀局部索引;

新建复合索引

db.users.createIndex({created:-1, name:1, age:1})

按照复合索引的反方向进行整体排序;

db.users.find().sort({created:1, name:-1, age:-1}).explain('executionStats'){    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {                    },        "winningPlan" : {            "stage" : "FETCH",            "inputStage" : {                "stage" : "IXSCAN",                "keyPattern" : {                    "created" : -1,                    "name" : 1,                    "age" : 1                },                "indexName" : "created_-1_name_1_age_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "created" : [ ],                    "name" : [ ],                    "age" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "backward",                "indexBounds" : {                    "created" : [                        "[MinKey, MaxKey]"                    ],                    "name" : [                        "[MaxKey, MinKey]"                    ],                    "age" : [                        "[MaxKey, MinKey]"                    ]                }            }        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 1000000,        "executionTimeMillis" : 1518,        "totalKeysExamined" : 1000000,        "totalDocsExamined" : 1000000,        "executionStages" : {            "stage" : "FETCH",            "nReturned" : 1000000,            "executionTimeMillisEstimate" : 1364,            "docsExamined" : 1000000,            "inputStage" : {                "stage" : "IXSCAN",                "nReturned" : 1000000,                "executionTimeMillisEstimate" : 816,                "keyPattern" : {                    "created" : -1,                    "name" : 1,                    "age" : 1                },                "indexName" : "created_-1_name_1_age_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "created" : [ ],                    "name" : [ ],                    "age" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "backward",                "indexBounds" : {                    "created" : [                        "[MinKey, MaxKey]"                    ],                    "name" : [                        "[MaxKey, MinKey]"                    ],                    "age" : [                        "[MaxKey, MinKey]"                    ]                },                "keysExamined" : 1000000            }        }    }}

排序使用索引前缀,也需要保证字段的顺序,但是可以反方向排序;

db.users.find().sort({created:1, name:-1, age:-1}).explain('executionStats'){    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {                    },        "winningPlan" : {            "stage" : "FETCH",            "inputStage" : {                "stage" : "IXSCAN",                "keyPattern" : {                    "created" : -1,                    "name" : 1,                    "age" : 1                },                "indexName" : "created_-1_name_1_age_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "created" : [ ],                    "name" : [ ],                    "age" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "backward",                "indexBounds" : {                    "created" : [                        "[MinKey, MaxKey]"                    ],                    "name" : [                        "[MaxKey, MinKey]"                    ],                    "age" : [                        "[MaxKey, MinKey]"                    ]                }            }        },        "rejectedPlans" : [ ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 1000000,        "executionTimeMillis" : 1487,        "totalKeysExamined" : 1000000,        "totalDocsExamined" : 1000000,        "executionStages" : {            "stage" : "FETCH",            "nReturned" : 1000000,            "executionTimeMillisEstimate" : 1339,            "works" : 1000001,            "advanced" : 1000000,            "needTime" : 0,            "needYield" : 0,            "saveState" : 7845,            "restoreState" : 7845,            "isEOF" : 1,            "invalidates" : 0,            "docsExamined" : 1000000,            "alreadyHasObj" : 0,            "inputStage" : {                "stage" : "IXSCAN",                "nReturned" : 1000000,                "executionTimeMillisEstimate" : 769,                "works" : 1000001,                "advanced" : 1000000,                "needTime" : 0,                "needYield" : 0,                "saveState" : 7845,                "restoreState" : 7845,                "isEOF" : 1,                "invalidates" : 0,                "keyPattern" : {                    "created" : -1,                    "name" : 1,                    "age" : 1                },                "indexName" : "created_-1_name_1_age_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "created" : [ ],                    "name" : [ ],                    "age" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "backward",                "indexBounds" : {                    "created" : [                        "[MinKey, MaxKey]"                    ],                    "name" : [                        "[MaxKey, MinKey]"                    ],                    "age" : [                        "[MaxKey, MinKey]"                    ]                },                "keysExamined" : 1000000,                "seeks" : 1,                "dupsTested" : 0,                "dupsDropped" : 0,                "seenInvalidated" : 0            }        }    }}

排序如果使用的是非前缀的局部字典排序,name需要保证前边的字段是等值筛选操作才行;

db.users.find({created:new Date("2021-10-30T08:17:01.184Z")}).sort({name:-1}).explain('executionStats'){    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {            "created" : {                "$eq" : ISODate("2021-10-30T08:17:01.184Z")            }        },        "winningPlan" : {            "stage" : "FETCH",            "inputStage" : {                "stage" : "IXSCAN",                "keyPattern" : {                    "created" : -1,                    "name" : 1,                    "age" : 1                },                "indexName" : "created_-1_name_1_age_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "created" : [ ],                    "name" : [ ],                    "age" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "backward",                "indexBounds" : {                    "created" : [                        "[new Date(1635581821184), new Date(1635581821184)]"                    ],                    "name" : [                        "[MaxKey, MinKey]"                    ],                    "age" : [                        "[MaxKey, MinKey]"                    ]                }            }        },        "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,            "invalidates" : 0,            "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,                "invalidates" : 0,                "keyPattern" : {                    "created" : -1,                    "name" : 1,                    "age" : 1                },                "indexName" : "created_-1_name_1_age_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "created" : [ ],                    "name" : [ ],                    "age" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "backward",                "indexBounds" : {                    "created" : [                        "[new Date(1635581821184), new Date(1635581821184)]"                    ],                    "name" : [                        "[MaxKey, MinKey]"                    ],                    "age" : [                        "[MaxKey, MinKey]"                    ]                },                "keysExamined" : 0,                "seeks" : 1,                "dupsTested" : 0,                "dupsDropped" : 0,                "seenInvalidated" : 0            }        }    }}

六、搜索数据对索引命中的影响

MongoDB对index的选择是受到实际场景的数据影响比较大的,即与实际数据的分布规律有关,也跟实际筛选出来的数据有关系;所以我们对索引的优化测试都需要考虑实际的数据场景才行;

由于name的字段值筛选出来的key太多,不能充分利用index,所以MongoDB拒绝了name_1并选择了age_1;

db.users.find({        name:/^user/,        age:{$gte:110}    }).explain('executionStats')    {    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {            "$and" : [                {                    "age" : {                        "$gte" : 110                    }                },                {                    "name" : {                        "$regex" : "^user"                    }                }            ]        },        "winningPlan" : {            "stage" : "FETCH",            "filter" : {                "name" : {                    "$regex" : "^user"                }            },            "inputStage" : {                "stage" : "IXSCAN",                "keyPattern" : {                    "age" : 1                },                "indexName" : "age_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "age" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "forward",                "indexBounds" : {                    "age" : [                        "[110.0, inf.0]"                    ]                }            }        },        "rejectedPlans" : [            {                "stage" : "FETCH",                "filter" : {                    "age" : {                        "$gte" : 110                    }                },                "inputStage" : {                    "stage" : "IXSCAN",                    "keyPattern" : {                        "name" : 1                    },                    "indexName" : "name_1",                    "isMultiKey" : false,                    "multiKeyPaths" : {                        "name" : [ ]                    },                    "isUnique" : false,                    "isSparse" : false,                    "isPartial" : false,                    "indexVersion" : 2,                    "direction" : "forward",                    "indexBounds" : {                        "name" : [                            "[\"user\", \"uses\")",                            "[/^user/, /^user/]"                        ]                    }                }            }        ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 83215,        "executionTimeMillis" : 246,        "totalKeysExamined" : 83215,        "totalDocsExamined" : 83215,        "executionStages" : {            "stage" : "FETCH",            "filter" : {                "name" : {                    "$regex" : "^user"                }            },            "nReturned" : 83215,            "executionTimeMillisEstimate" : 232,            "works" : 83216,            "advanced" : 83215,            "needTime" : 0,            "needYield" : 0,            "saveState" : 658,            "restoreState" : 658,            "isEOF" : 1,            "invalidates" : 0,            "docsExamined" : 83215,            "alreadyHasObj" : 0,            "inputStage" : {                "stage" : "IXSCAN",                "nReturned" : 83215,                "executionTimeMillisEstimate" : 43,                "works" : 83216,                "advanced" : 83215,                "needTime" : 0,                "needYield" : 0,                "saveState" : 658,                "restoreState" : 658,                "isEOF" : 1,                "invalidates" : 0,                "keyPattern" : {                    "age" : 1                },                "indexName" : "age_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "age" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "forward",                "indexBounds" : {                    "age" : [                        "[110.0, inf.0]"                    ]                },                "keysExamined" : 83215,                "seeks" : 1,                "dupsTested" : 0,                "dupsDropped" : 0,                "seenInvalidated" : 0            }        }    }}

我们修改一下name筛选条件的值,进一步缩小命中的范围,可以看到这次MongoDB选择了name_1;

db.users.find({        name:/^user8888/,        age:{$gte:110}    }).explain('executionStats')    {    "queryPlanner" : {        "plannerVersion" : 1,        "namespace" : "test.users",        "indexFilterSet" : false,        "parsedQuery" : {            "$and" : [                {                    "age" : {                        "$gte" : 110                    }                },                {                    "name" : {                        "$regex" : "^user8888"                    }                }            ]        },        "winningPlan" : {            "stage" : "FETCH",            "filter" : {                "age" : {                    "$gte" : 110                }            },            "inputStage" : {                "stage" : "IXSCAN",                "keyPattern" : {                    "name" : 1                },                "indexName" : "name_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "name" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "forward",                "indexBounds" : {                    "name" : [                        "[\"user8888\", \"user8889\")",                        "[/^user8888/, /^user8888/]"                    ]                }            }        },        "rejectedPlans" : [            {                "stage" : "FETCH",                "filter" : {                    "name" : {                        "$regex" : "^user8888"                    }                },                "inputStage" : {                    "stage" : "IXSCAN",                    "keyPattern" : {                        "age" : 1                    },                    "indexName" : "age_1",                    "isMultiKey" : false,                    "multiKeyPaths" : {                        "age" : [ ]                    },                    "isUnique" : false,                    "isSparse" : false,                    "isPartial" : false,                    "indexVersion" : 2,                    "direction" : "forward",                    "indexBounds" : {                        "age" : [                            "[110.0, inf.0]"                        ]                    }                }            }        ]    },    "executionStats" : {        "executionSuccess" : true,        "nReturned" : 10,        "executionTimeMillis" : 0,        "totalKeysExamined" : 112,        "totalDocsExamined" : 111,        "executionStages" : {            "stage" : "FETCH",            "filter" : {                "age" : {                    "$gte" : 110                }            },            "nReturned" : 10,            "executionTimeMillisEstimate" : 0,            "works" : 114,            "advanced" : 10,            "needTime" : 102,            "needYield" : 0,            "saveState" : 1,            "restoreState" : 1,            "isEOF" : 1,            "invalidates" : 0,            "docsExamined" : 111,            "alreadyHasObj" : 0,            "inputStage" : {                "stage" : "IXSCAN",                "nReturned" : 111,                "executionTimeMillisEstimate" : 0,                "works" : 113,                "advanced" : 111,                "needTime" : 1,                "needYield" : 0,                "saveState" : 1,                "restoreState" : 1,                "isEOF" : 1,                "invalidates" : 0,                "keyPattern" : {                    "name" : 1                },                "indexName" : "name_1",                "isMultiKey" : false,                "multiKeyPaths" : {                    "name" : [ ]                },                "isUnique" : false,                "isSparse" : false,                "isPartial" : false,                "indexVersion" : 2,                "direction" : "forward",                "indexBounds" : {                    "name" : [                        "[\"user8888\", \"user8889\")",                        "[/^user8888/, /^user8888/]"                    ]                },                "keysExamined" : 112,                "seeks" : 2,                "dupsTested" : 0,                "dupsDropped" : 0,                "seenInvalidated" : 0            }        }    }}

以上就是关于“MongoDB中什么情况下索引会选择策略”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

--结束END--

本文标题: MongoDB中什么情况下索引会选择策略

本文链接: https://www.lsjlt.com/news/321478.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MongoDB中什么情况下索引会选择策略
    这篇“MongoDB中什么情况下索引会选择策略”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“MongoDB中什么情况下索引会...
    99+
    2023-06-29
  • MongoDB中哪几种情况下的索引选择策略
    目录一、MongoDB如何选择索引二、数据准备三、正则对index的使用四、$or从句对索引的利用五、sort对索引的利用六、搜索数据对索引命中的影响总结一、MongoDB如何选择索...
    99+
    2024-04-02
  • mysql索引什么情况下会失效
    mysql索引在不使用索引列进行查询、数据类型不匹配、前缀索引的使用不当、使用函数或表达式进行查询、索引列的顺序不正确、数据更新频繁和索引过多或过少情况下会失效。1、不使用索引列进行查询,为了避免这种情况,应该在查询中使用适当的索引列;2、...
    99+
    2023-08-09
  • mysql中什么情况会导致索引失效
    这篇文章主要为大家展示了“mysql中什么情况会导致索引失效”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“mysql中什么情况会导致索引失效”这篇文章吧。为了讲解以下索引内容,我们先建立一个临时...
    99+
    2023-06-25
  • MySQL调优之索引在什么情况下会失效详解
    目录前言【1】全值匹配我最爱【2】最佳左前缀法则【3】主键插入顺序【4】计算、函数、类型转换(自动或手动)导致索引失效【5】范围条件右边的列索引失效【6】不等于(!=或者 <>) 索引失效【7】is null...
    99+
    2024-04-02
  • MongoDB索引策略与优化的方法是什么
    MongoDB的索引策略和优化方法包括以下几个方面: 选择合适的字段建立索引:根据查询需求和数据访问模式选择需要建立索引的字段,...
    99+
    2024-05-07
    MongoDB
  • MySQL数据库中什么情况下需要使用索引
    这篇文章主要介绍MySQL数据库中什么情况下需要使用索引,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!什么情况下需要使用索引(1)列经常被用于where条件中(2)列中有大...
    99+
    2024-04-02
  • MongoDB 中索引选择B-树的原因是什么
    这期内容当中小编将会给大家带来有关MongoDB 中索引选择B-树的原因是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、B-树和B+树的区别很明显,我们要想弄清楚...
    99+
    2024-04-02
  • MySQL中有哪些情况下数据库索引会失效详析
    前言 要想分析MySQL查询语句中的相关信息,如是全表查询还是部分查询,就要用到explain. 索引的优点 大大减少了服务器需要扫描的数据量 可以帮助服务器避免排序或减少使用临时表排序 索引...
    99+
    2024-04-02
  • 什么情况下选择购买海外云服务器
    购买海外云服务器的情况有:1、不想备案的企业,使用海外云服务器不用备案,能省去繁琐的备案流程和时间;2、业务遍布范围广的企业,使用海外云服务器能满足不同人群的多样化需求,有利于网站的发展;3、研究型离岸企业或机构,使用海外云服务器能查询一些...
    99+
    2024-04-02
  • Angular中什么是变更检测?什么情况下会引起变更检测?
    Angular中什么是变更检测?下面本篇文章带大家了解一下变更检测,并介绍一下什么情况下会引起变更检测,希望对大家有所帮助!什么是变更检测?简单来说,变更检测就是Angular用来检测视图与模型之间绑定的值是否发生了改变,当检测到模型中的值...
    99+
    2023-05-14
    Angular 变更检测
  • java项目中什么情况下HashCode会出现重复
    java项目中什么情况下HashCode会出现重复?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。java的缺省算法:  public int&...
    99+
    2023-05-31
    java hashcode 情况下
  • Android开发中什么情况下会出现内存泄漏
    今天就跟大家聊聊有关Android开发中什么情况下会出现内存泄漏,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。 android中一个对象已经不需要了,但是其他对象还持有他的...
    99+
    2023-05-31
    android 情况下 roi
  • 企业在什么情况下要选择租用高防服务器
    企业选择租用高防服务器的原因:1.高防服务器可以有效地防御任何CC攻击,DDOS,SYN攻击等常见网络攻击,保证企业处于安全稳定的网络环境。2.高防服务器可以有效防御服务器受到攻击,避免计算机出现系统崩溃,用户的数据资料丢失等情况。3.专业...
    99+
    2024-04-02
  • 索引和打包:Python 中的实时优化策略是什么?
    在数据处理领域中,索引和打包是非常重要的概念。在 Python 中,实时优化策略可以帮助我们更好地利用这些概念来提高数据处理的效率。本文将介绍索引和打包的概念,并提供一些实时优化策略的示例代码。 一、索引和打包的概念 索引是指通过某种方式...
    99+
    2023-10-29
    索引 实时 打包
  • 什么情况下应选择使用Aurora相对于其他数据库服务
    需要高性能和可伸缩性:Aurora是一个高性能、高可用性的关系型数据库服务,可以处理大规模的工作负载,并且能够自动进行水平扩展和故...
    99+
    2024-04-09
    Amazon
  • 为什么在PHP中使用索引数组而不是对象数组?JavaScript是否也有类似的选择?
    在PHP中,索引数组和对象数组是两种非常常见的数据结构。索引数组是一个从0开始的整数序列,每个元素都有一个唯一的整数索引。而对象数组则是由对象组成的数组,每个对象都有一个唯一的键值。那么为什么在PHP中使用索引数组而不是对象数组呢?Java...
    99+
    2023-08-09
    索引 对象 javascript
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作