monggo索引优化

mongodb索引规则

mongodb索引规则基本上与传统的关系库一样,大部分优化MySQL/Oracle/SQLite索引的技巧也适用于mongodb。

为什么用索引

  • 当查询中用到某些条件时,可以对该键建立索引,以提高查询速度。
  • 数据量多且查询多余更新时,可以用索引提高查询速度。

废话不多说,先上图,后再说

  • 表总数据2000万+
    jdk

  • 查询表索引情况
    jdk

  • 查询在没有建立索引情况下执行
    jdk

  • 对需要过滤字段建立索引(此时数据库拥有2000万+数据,执行时间89s)
    jdk

  • 查询表索引情况(已建立)
    jdk

  • 查询在建立了索引情况下执行
    jdk
    ()建立了索引查询2000万数据速度从30秒减少到1毫秒,这效率牛逼了!

    注意:建立索引尽量在创建表时创建,不然当表数据过大,创建索引会消耗大量时间和cpu

有点影响,但是不大

当然使用索引是也是有代价的:对于添加的每一条索引,每次写操作(插入、更新、删除)都将耗费更多的时间。这是因为,当数据发生变化时,不仅要更新文档,还要更新级集合上的所有索引。因此,mongodb限制每个集合最多有64个索引。

常用操作

唯一索引

  db.launcher4k20170628.ensureIndex({"name":1},{"unique":true})

单列索引

  db.launcher4k20170628.ensureIndex({positionCode:1},{name:'positionCode_index'})

复合索引

索引的值是按一定顺序排列的,所以使用索引键对文档进行排序非常快。

  db.launcher4k20170628.ensureIndex({positionCode:1,launcherType:1},{name:'position_index'})

查看我们建立的索引

  db.launcher4k20170628.getIndexes()

删除索引

  //删除单个
  db.launcher4k20170628.dropIndex('name')

  //删除全部
  db.launcher4k20170628.dropIndex('*')

使用explain

explain是非常有用的工具,会帮助你获得查询方面诸多有用的信息。只要对游标调用该方法,就可以得到查询细节。explain会返回一个文档,而不是游标本身。如:
jdk
explain会返回查询使用的索引情况,耗时和扫描文档数的统计信息。

项目实践

统计功能,每天凌晨定时从mongo统计数据到mysql。但是随着数据量增大,最高数据达到9000万+数据,要对这如此庞大数据进行统计,避免不了使用索引以及mongo聚合函数。

因之前没有添加索引,造成了一诸多问题。例如之前文章中提到的[MongoDB 查询超时异常 SocketTimeoutException]
经常造成连接池杠不住,以及查询时长过长造成连接不上monggo等问题。

org.springframework.dao.DataAccessResourceFailureException: Read operation to server 172.23.5.7:9343 failed on database launcher4k;
 nested exception is com.mongodb.MongoException$Network: Read operation to server 172.23.5.7:9343 failed on database launcher4k
	at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:59)
	at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:1926)
	at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:396)
	at org.springframework.data.mongodb.core.MongoTemplate.executeCommand(MongoTemplate.java:336)
	at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1425)
	at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1360)
	at com.amt.modules.dao.OprationDaoImpl.getCountsTime(OprationDaoImpl.java:123)
	at com.amt.modules.service.OprationServiceImpl.saveCountsTime(OprationServiceImpl.java:379)
	at com.amt.modules.common.ContentTaskMethod.moveDateMongoToMysql(ContentTaskMethod.java:56)
	at com.amt.modules.common.SystemTask.createStatisticData(SystemTask.java:45)
	at sun.reflect.GeneratedMethodAccessor2305.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

可以通过配置mongo文件进行优化,但这不是长远之计。

      mongo.connectionsPerHost=8
      mongo.threadsAllowedToBlockForConnectionMultiplier=4
      mongo.connectTimeout=1000
      mongo.maxWaitTime=2000 //最大连接时长 秒为单位
      mongo.autoConnectRetry=true
      mongo.socketKeepAlive=true
      mongo.socketTimeout=0
      mongo.slaveOk=true

这就需要索引来大大的调高查询速度

  • 创建联合索引
    //方法过时了
    private void createIndex(String name){
     IndexOperations  io=mongoTemplate.indexOps(name);
     Index index =new Index();
       index.on("positionCode",Order.ASCENDING);
       index.on("positionName",Order.ASCENDING);
       index.on("launcherType",Order.ASCENDING);
       index.on("terminalId",Order.ASCENDING);
       index.on("labelId",Order.ASCENDING);
       io.ensureIndex(index);
    }
    //正常
    private void createIndex(String name){
       DBObject indexOptions = new BasicDBObject();
       indexOptions.put("positionCode", 1);
       indexOptions.put("positionName", 1);
       indexOptions.put("launcherType.d", 1);
       indexOptions.put("labelId", 1);
       CompoundIndexDefinition indexDefinition =new CompoundIndexDefinition(indexOptions);
       mongoTemplate.indexOps(name).ensureIndex(indexDefinition);
	  }

    public void create(OprationEntity opration) throws Exception {
    mongoTemplate.insert(opration, getTableName(opration.getUpdateTime()));
    this.createIndex(getTableName(opration.getUpdateTime()));
    }

jdk

  • 创建单列索引
  /**
   * 添加索引
   * @param string
   */
  @SuppressWarnings("deprecation")
  private void createIndex(String name){
     IndexOperations  io=mongoTemplate.indexOps(name);
       io.ensureIndex(new Index().on("positionCode", Order.ASCENDING));
       io.ensureIndex(new Index().on("positionName", Order.ASCENDING));
       io.ensureIndex(new Index().on("launcherType", Order.ASCENDING));
       io.ensureIndex(new Index().on("labelId", Order.ASCENDING));
  }

注意:在测试创建索引是否成功我手动去删了库,然后执行创建索引就创建无效。但是如果新创建表为其创建索引的,就会生成索引值。

jdk

[mongoTemplate参考文档地址]

转载请注明出处:[www.updatecg.xin]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

践者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值