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

关于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。

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值