关于mongodb中选择性低的字段排序问题

今天在开发公司评论系统的新需求时,碰到一个关于mongo sort排序的问题

条件:
1. 评论表comment中包含两个字段 ctime(添加时间),like(点赞的人数)
2. comment表中的数据为1000万+
3. 无索引(没有给ctime,like添加任何索引)
4. php查询mongo的超时时间设置的是1s

查询:

db.comment.find().skip(0).limit(*).sort({'ctime':-1})
//按照ctime排序
没有报错,查询时间不到1s

db.comment.find().skip(0).limit(*).sort({'like':-1})
//按照like排序
报错:超时,发现查询时间为2s到3s

图片描述
此图为无索引

为什么会出现这个问题呢?当时很困惑,ctime与like的级别是一样的,都没有加索引且都是int型数据,为什么一个查询不到1s,一个要2s+?

突然一道金光射入我的脑子我一下就明白了!!
因为如果按ctime排序的话,这个数组就为有序数组,如果按like排序的话,这个数组就为无序数组无序数组排序比有序排序的时间复杂度要大

note:一条记录在添加时ctime是递增的,而like是离散的数字

问题现在搞清楚了,现在怎么解决呢?

怎样才能让db.comment.find().skip(0).limit(*).sort({'like':-1})的查询效率变高?

在不影响业务的情况下,我选择了给like添加索引,但如何添加索引是个问题了。一般我们都知道不给选择性低的字段添加索引,因为这个不能提高效率。那该如何做呢?

答案:就是添加组合索引

策略是创建组合索引包括这个低选择性的字段。(即:选择性高的字段+选择性低的字段)

方案一

db.comment.ensureIndex({'ctime':1,'like':-1})
//添加组合索引
db.comment.find().skip(0).limit(*).sort({'like':-1})

图片描述
此图索引为{'ctime':1,'like':-1}
从图上看出,还是索引没有起作用,这是因为组合索引中,用右边的字段索引,索引不起作用。

方案二

db.comment.ensureIndex({'like':-1,'ctime':1})
//添加组合索引
db.comment.find().skip(0).limit(*).sort({'like':-1})

图片描述
此图索引为{'like':-1,'ctime':1}
发现效率明显提高了很多

了解组合索引的优化原理请读:10gen工程师谈MongoDB组合索引的优化

关于mysql数据库索引 http://www.uml.org.cn/sjjm/201107145.asp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值