关于3种sql,两个索引,对应的mongodb优化选择的是哪个索引呢?
发布日期:2021-06-29 13:15:32 浏览次数:2 分类:技术文章

本文共 2092 字,大约阅读时间需要 6 分钟。

关于3种sql,两个索引,对应的mongodb优化选择的是哪个索引呢?

脚本1

db.QuickReplyTemplate.find({    "sceneKey": "responseMsg",    "termId": {"$in":["1","2","3"]},    "isDelete": false}).sort({"updatedOn":-1}).explain("executionStats");

 

脚本2

db.QuickReplyTemplate.find({    "sceneKey": "responseMsg",    "termId": "1",    "isDelete": false}).sort({"updatedOn":-1}).explain("executionStats");

 

脚本3

db.QuickReplyTemplate.find({    "sceneKey": "responseMsg",    "isDelete": false}).sort({"updatedOn":-1}).explain("executionStats");

 

 

索引1

db.getCollection("QuickReplyTemplate").createIndex({    sceneKey: NumberInt("1"),    termId: NumberInt("1"),    isDelete: NumberInt("1"),    updatedOn: NumberInt("1")}, {    name: "idx_QuickReplyTemplate__sceneKey_1_termId_1_isDelete_1_updatedOn_1"});
db.getCollection("QuickReplyTemplate").createIndex({    sceneKey: NumberInt("1"),    isDelete: NumberInt("1"),    updatedOn: NumberInt("1")}, {    name: "idx_QuickReplyTemplate__sceneKey_1_isDelete_1_updatedOn_1"});

 

 

分析:

我们先大胆猜测一下,脚本1使用的是哪个索引?脚本2使用的是哪个索引?脚本3呢?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

此处减少空间,直接粘出最优选择

这是脚本1的最优选择(是的,我们可以看出,他选择了索引2,并没有选择索引1)

 

至于为什么没有选择索引1呢?因为他排除了,我们去看看

这里没有粘出所有分析计划,但是我们可以从上述看出,他使用了排序合并的计划,也就是 $in关键字导致,所以他认为,范围查询,不能精确命中,所以将其排除;

 

 

那么看看脚本2吧,脚本2就是为了对比脚本1,看看他选择了什么索引

是的,可以和我们预料的是一致,由于此次termId字段只有一个值,那么他将选择索引1,因为命中率更高。

 

 

 

那么我们看看脚本3的执行计划吧

毋庸置疑,索引2更为合适,那么此处就不用分析了,很清晰

  

他如果选择了索引1,那么就会出现索引中断现象,那么对于后面的排序,那么就会出现内存排序现象

虽然是在索引命中的前提下进行的内存排序

 

 

结论:那么好坏对比,相比大家都分析出来了。最好的解决方法就是两个索引都留着,都可以选择最优的索引。

 

db.getCollection("QuickReplyTemplate").createIndex({    sceneKey: NumberInt("1"),    termId: NumberInt("1"),    isDelete: NumberInt("1"),    updatedOn: NumberInt("1")}, {    name: "idx_QuickReplyTemplate__sceneKey_1_termId_1_isDelete_1_updatedOn_1"});
db.getCollection("QuickReplyTemplate").createIndex({    sceneKey: NumberInt("1"),    isDelete: NumberInt("1"),    updatedOn: NumberInt("1")}, {    name: "idx_QuickReplyTemplate__sceneKey_1_isDelete_1_updatedOn_1"});

但是大家没有发现,两个索引基本是很类似的,那么如果两个都留下,很显然,并不是一个很好的方式,这种复合索引设计,不是很好的一个设计方案,必须选择留下其一。

那到底留下哪个?其实得根据具体业务来,上述3个脚本,都是笔者业务中会出现的查询条件组合,那么笔者需要根据业务出现的频率,并且sql面向的对象进行选择取舍。

 

最后笔者,还是选择了留下索引2。

 

这个文章给大家提供一个思路,一个分析项目执行效率的优化角度方案,思路。

转载地址:https://changemax.blog.csdn.net/article/details/111224978 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:UNIX网络编程 5种IO模型
下一篇:关于设计mongodb索引,涉及到内存排序问题解决

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月17日 11时22分05秒