日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

MongoDB 優(yōu)化

 CevenCheng 2011-07-15


優(yōu)化一個簡單的例子

這部分主要講解如何優(yōu)化MongoDB的性能。

讓我們舉個具體示例。假使我們的任務(wù)是現(xiàn)實blog的首頁-我們希望現(xiàn)實最近發(fā)布的10條posts。ts為時間字段。

語句如下

articles = db.posts.find().sort({ts:-1}); 
// get blog posts in reverse time order
for (var i=0; i< 10; i++) 
{   print(articles[i].getSummary());}
優(yōu)化 #1: 創(chuàng)建索引

第一個優(yōu)化就是要在ts上創(chuàng)建索引,用來快速排序。

db.posts.ensureIndex({ts:1});

使用索引,數(shù)據(jù)庫就可以基于索引信息排序,不會直接查看每個document。這樣做更快。

優(yōu)化#2: 限定結(jié)果

MongoDB游標(biāo)返回一組document,我們叫這個為chunks。

這chunk可能包含超過10個對象。額外的對象對于我們的需求是浪費,

浪費了網(wǎng)絡(luò)帶寬和應(yīng)用服務(wù)器以及數(shù)據(jù)庫的資源。

我們知道想要結(jié)果的個數(shù),那么就不需要所有的結(jié)果。我們可以使用limit()方法

articles = db.posts.find().sort({ts:-1}).limit(10); 
// 最多10條

現(xiàn)在,我們從客戶端返回了10條。

優(yōu)化 #3: 查詢相關(guān)的字段

post對象非常大, 如post文本和評論數(shù)組。 比較好的方式是只查詢我們要用到的字段。

articles = db.posts.find({}, {ts:1,title:1,author:1,abstract:1}).sort({ts:-1}).limit(10);
articles.forEach( function(post) { print(post.getSummary()); } );

上面的getSummary()方法假使是可以獲得find()方法返回的字段值

注意,如果你選擇了要查詢的字段,那么返回的就是部分對象。這個對象并不能直接進(jìn)行更新。如下

a_post = db.posts.findOne({}, Post.summaryFields);
a_post.x = 3;
db.posts.save(a_post); // 錯誤,拋出異常

使用 Profiler

MongoDB有一個數(shù)據(jù)庫的 profiler,用來顯示每個操作的性能。

使用profiler你可以查看到哪些查詢或者寫入的速度比較慢。

舉個例子,使用這些信息可以知道什么時候需要索引。詳情查看 Database Profiler 。

 Use count()優(yōu)化語句

加速語句速度依賴于count(),創(chuàng)建一個索引,調(diào)用count()。

db.posts.ensureIndex({author:1});
db.posts.find({author:"george"}).count();

增量操作Increment Operations

MongoDB 支持簡單對象字段的增量操作; 

基本上來說, 這個操作就是 在服務(wù)器document中增量一個字段"。

這個要比"獲取一個document,更新這個字段并且在保存會服務(wù)器"這個方法快很多,

并且對于實時的計數(shù)器更為有用。詳情請看  Updates 。

固定大小的collection。

MongoDB提供了一個特殊的collection,它提前分配好了存儲空間。

保存的項都是固定順序的,并且沒有索引。而且寫入和讀取是非常高速的。

存儲是為了保存日志文件所設(shè)置的。詳情查看 Capped Collections 

服務(wù)端代碼執(zhí)行Server Side Code Execution

也許有的時候為了高性能,避免客戶端和服務(wù)端來回通信,需要直接在服務(wù)端執(zhí)行代碼。

這部分查看 Server-Side Processing 。

Explain工具

要想查看查詢語句的詳細(xì)性能信息,最好的方法就是使用explain方法。

返回的結(jié)果就是整個查詢執(zhí)行的一些信息。

當(dāng)使用shell的時候,可以調(diào)用cursor的explain() 方法。

db.collection.find(query).explain();

返回的信息如下

{"cursor" : "BasicCursor",    
"indexBounds" : [ ],    
"nscanned" : 57594,    
"nscannedObjects" : 57594,    
"nYields" : 2 ,    
"n" : 3 ,    
"millis" : 108,    
"indexOnly" : false}
現(xiàn)實結(jié)果可以得知cursor的類型,DB掃描的數(shù)據(jù)數(shù),返回的數(shù)據(jù)數(shù),還有執(zhí)行的毫秒數(shù)。

  • nscanned - 掃描的數(shù)據(jù)條數(shù)。這個數(shù)據(jù)可能是對象也可能是索引的鍵。
  • 如果"覆蓋索引(covered index)"被調(diào)用了,nscanned 要高于nscannedObjects.
  • nscannedObjects - 掃描對象的數(shù)。
  • nYields - 查詢所產(chǎn)生的鎖的個數(shù)。
  • indexOnly - 是否使用了covered index。

Hint

雖然MongoDB查詢優(yōu)化器一般工作的很不錯,但是也可以使用hints來強(qiáng)迫MongoDB使用一個指定的索引。

這種方法某些情形下會提升性能。 一個有索引的collection并且執(zhí)行一個多字段的查詢(一些字段已經(jīng)索引了)。

傳入一個指定的索引,強(qiáng)迫查詢進(jìn)行使用。

 

db.collection.find({user:u, foo:d}).hint({user:1});
確定創(chuàng)建了索引。
上面的例子,首先你確定索引已經(jīng)創(chuàng)建了。請使用ensureIndex()創(chuàng)建索引。

其他的例子,有個在 {a:1, b:1} 上的索引,名稱為"a_1_b_1":

db.collection.find({a:4,b:5,c:6}).hint({a:1,b:1});
db.collection.find({a:4,b:5,c:6}).hint("a_1_b_1");

強(qiáng)迫查詢不適用索引, (做一個表的掃描), 使用:

> db.collection.find().hint({$natural:1})

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多