2015-11-08 20:58:51.0|分类: MongoDB|浏览量: 6570
1、mongo查询优化 DBCursor cur = collection.find(); MongoCursor<Document> cursor = cur.iterator(); try { while (cursor.hasNext()) { System.out.println(cursor.next().toJson()); } } finally { cursor.close(); } mongodb查询query方法要慎用。如果想要查询一个表的所有数据请用cur.iterator()方法。慎用cur.toArray(),这个方法把所有的数据都放到内存中,如果数据量很大,你想想会出现什么情况。 cur.length()同样慎用,这个原因和cur.toArray()一样,也会把所有数据读到内存中,然后得到list大小。 cur.size()同样是获取cur这个游标大小,但是他的原理是再次执行一次查询数据库得到大小,源码如下: public int size() { return (int)_collection.getCount(this._query, this._keysWanted, this._limit, this._skip, getReadPreference(), _maxTimeMS, MILLISECONDS); } 2、mongo连接池分析 今天发现网站运行特别慢,pc浏览器和手机接口传输数据都很慢。最近网站都没有更新,运行了一段时间发现自动慢下来了。mongo连接池如下: mongo = new MongoClient(ip, port); // 设置链接参数 mongo.getMongoClientOptions().builder() .connectionsPerHost(SystemProperties.getMongoPoolSize()) .socketTimeout(SystemProperties.getMongoSocketTimeout()) .socketKeepAlive(SystemProperties.getMongoSocketKeepAlive()) .threadsAllowedToBlockForConnectionMultiplier(SystemProperties.getMongoThreads()) .build(); // 完成参数设置 mongno默认的配置信息
关系型数据库中,我们做连接池无非就是事先建立好N个连接(connection),并构建成一个连接池(connection pool),获取连接和释放链接的操作 Mongo m = new Mongo( "localhost" , 27017 ); DB db = m.getDB( "mydb" ); //get collection DBCollection coll = db.getCollection("testCollection") //insert BasicDBObject doc = new BasicDBObject(); ... coll.insert(doc); 官方解释: Note: The Mongo object instance actually represents a pool of connections to the database; you will only need one object of class Mongo even with multiple threads. See the concurrency doc page for more information. The Mongo class is designed to be thread safe and shared among threads. Typically you create only 1 instance for a given DB cluster and use it across your app. If for some reason you decide to create many mongo intances, note that:all resource usage limits (max connections, etc) apply per mongo instance to dispose of an instance, make sure you call mongo.close() to clean up resources。 mongo实例其实已经是一个现成的连接池了,而且线程安全。这个内置的连接池默认初始了10个连接,每一个操作(增删改查等)都会获取一个连接,执行操作后释放连接。 分析插入源代码: DBCollectionImpl extends DBCollection 类中 public WriteResult insert(List<DBObject> list, WriteConcern concern, DBEncoder encoder ){ return insert(list, true, concern, encoder); } protected WriteResult insert(List<DBObject> list, boolean shouldApply , WriteConcern concern, DBEncoder encoder ){ if (concern == null) { throw new IllegalArgumentException("Write concern can not be null"); } if (encoder == null) encoder = DefaultDBEncoder.FACTORY.create(); if ( willTrace() ) { for (DBObject o : list) { trace("save: " + namespace + " " + JSON.serialize(o)); } } DBPort port = db.getConnector().getPrimaryPort(); try { if (useWriteCommands(concern, port)) { try { return translateBulkWriteResult(insertWithCommandProtocol(list, concern, encoder, port, shouldApply), INSERT, concern, port.getAddress()); } catch (BulkWriteException e) { throw translateBulkWriteException(e, INSERT); } } else { return insertWithWriteProtocol(list, concern, encoder, port, shouldApply); } } finally { db.getConnector().releasePort(port); } } 上面代码插入完成之后都会执行finally代码: db.getConnector().releasePort(port);释放资源。 |