2016-07-27 20 views
-2

私たちはゲームでmongo dbをリアルタイムデータベースとして使用することに決めましたが、検索結果のパフォーマンスは受け入れられません。これらは15,000文書と17フィールド(文字列、int、float)のテスト結果ですUnity GameのMongoDBパフォーマンスの問題

// 14000 ms 
    MongoUrl url = new MongoUrl("url-adress"); 
    MongoClient client = new MongoClient(url); 
    var server = client.GetServer(); 
    var db = server.GetDatabase("myDatabase"); 
    var collection = db.GetCollection<PlayerFields>("Player"); 

    var ranks = collection.FindAll().AsQueryable().OrderByDescending(p=>p.Score).ToList().FindIndex(FindPlayer).Count(); 

これは最悪です。 // ToList()はテストのためのものです。実動コードでは使用しないでください。

セカンドテスト

 //9000 ms 
     var ranks = collection.FindAll().AsQueryable().Where(p=>p.Score < PlayerInfos.Score).Count(); 

第三に、テスト

//2000 ms 
var qq = Query. GT("Kupa", player.Score); 
    var ranks = collection.Find(qq).Where(pa=>(pa.Win + pa.Lose + pa.Draw) != 0); 

C#.NET 2.0とモンゴで高速な検索を行うための他の方法はあります。私たちは、ユーザーの得点に応じてプレーヤーのランクを得てランク付けしたいと考えています。

+0

私はDBについてこの部分に熟練していませんが、この情報を提供するAPIを使用していますか?したがって、ページを呼び出すだけで、サーバーがそのページを取得します。 – matiaslauriti

+0

コレクションインデックスを提供できますか?問題の診断に役立つことがあります – justcompile

+0

ObjectIdフィールドである1つのインデックスのみ。 –

答えて

2

これは注意してください、私は数年前から.NET開発者ではなかったので、もしC#ドライバに問題があるなら、本当にコメントすることはできませんが、モンゴはそううまくいけば、私がお手伝いします...

インデックスは

インデックスはここに多くのことをあなたを助けます。索引付けされていないフィールドを注文したりフィルタリングしたりするので、データベースが大きくなると問題が発生します。

インデックスは、方向に固有の(昇順/降順)インデックスです。

db.player.ensureIndex({'Score': -1}) // -1 indicating descending 

クエリ

また、モンゴは(私の意見では)本当に素晴らしいですし、あなたがそれを使用しているように、それは見ていません:あなたのフィールドが降順インデックスを作成する必要がある「スコア」という意味それが最高のものであること。

あなたの最初の呼び出し:で、その後、あなたはコレクション全体ToList()を取得していることメモリ(FindPlayer predicate)でそれをフィルタリングそれが表示されます

var ranks = collection.FindAll().AsQueryable().OrderByDescending(p=>p.Score).ToList().FindIndex(FindPlayer).Count(); 

は(私の.NETの知識が私をダウンさせることもできる場所です)データのサブセットを検索する。私はこれがあなたのアプリケーションのメモリにカーソル全体(15.000文書)を評価すると信じています。

Mongoがアプリケーションではなく作業を行うようにクエリを更新する必要があります。

を考えると、あなたの他のクエリが大幅にあなたが期待しているコールをするときにする場合

プロファイリングこれらの他のクエリ

のパフォーマンスを向上させる必要があり、上記のようインデックスを追加、Scoreにフィルタリングされていますmongo cliからの実行が予想どおりに動作していれば、ドライバがわずかに異なるクエリを作成している可能性があります。MongoのCLIで

、あなたが最初のプロファイルを設定する必要があります。

db.setProfilingLevel(2) 

あなたは、実際に行われているかのクエリを参照するプロファイル収集を照会できます。

db.system.profile.find().limit(5).sort({ts: -1}).pretty() 

この意志最近の5件の通話を表示します。

+1

.ToList()を呼び出すと、メモリ内のレイジーローディングアイテムが評価されるので、あなたの前提は正しいと思います。 – Liam

+0

@justcompileはい、あなたは正しいです。プロダクトコードで.ToList()を使用しないのは、テスト目的のみです。スコアにインデックスを作成した後、私は同じクエリを3番目の方法で呼び出すでしょうか? –

+0

インデックスを作成してこのようなクエリを見つけようとします。\t var pla = Query.EQ( "UserID"、PlayerInfos.userID); \t \t PlayerFields rPlayer = playerData.PlayerInfo.Find(新しいQueryDocument( "UserID"、PlayerInfos.userID)))First();それは5000msを興奮させた。私はmongodbで何が起こっているのか分かりません。これらの戻り時間は非常に遅いです! –

関連する問題