2016-12-28 3 views
1

私のウェブサイト(MEAN.JSを使用)には1つのログインページがあり、複数の統計ページ(データはデータベースのデータに基づいて作成されています)もあります。mongodbへの問い合わせが多いため、ウェブサイトがハングアップする

1つの重いレポートがデータベースから100MBを引き出し、10秒で完了します。問題はこのレポートを実行しているときに、MongoDBへのクエリーを実行するときに他のWebページのほとんどがブラウザに読み込まれないことです。たとえば、ログインページのUIが既に表示されている場合でも、ログインページにログインすることはできません。

MongoDBは複数のクエリを並列に実行することも、クエリキューだけを実行することもできますか?

MongoDBサーバーのバージョンはv3.2.3です。このレポートでは、ユーザー、トラッキングサイトの2つのコレクションが使用されます。私は月のレポートを作成しています:

30 days * 100 users * 10000 gps locations/day/user 
= 30 million locations 

user: { 
    username: (string), 
    organization: (objectid) 
} 

trackinglocation: { 
    username: (string), 
    date: (date), 
    locations: [ 
     { 
      speed: (number), 
      long: (number), 
      lat: (number) 
     } 
    ] 
} 

私は最初に管理者の組織内のユーザーを検索します。次に、その組織内のユーザーの移動距離のレポートを日付範囲内で作成するためのクエリを実行します。

ログインページだけでなく、レポート作成時に10秒間、他の多くのページがブラウザに応答しません(UI部分はまだExpressJSによって応答されますが、データテーブルは応答されません)。

+0

使用しているmongoのバージョンを教えてください。クエリは、レポートとユーザーのログインに同じコレクションを使用しますか?どんなタイプの重いクエリを使用しますか?また、どのストレージエンジンを使用していますか?すべてのことが重要です。 –

+0

mongodb server v3.2.3では、このレポートでは2つのコレクション、users、trackinglocations、これはおそらく他の多くの掛け金と干渉します。私は質問に詳細を追加しました – johnlowvale

答えて

1

状況はmongodbに限定されません。はい、並列でクエリを実行できますが、特に大きなレポートを起動すると、並列化の優れた他のデータベースシステムでも停止する可能性があります。

これを軽減する一般的なアプローチは、セカンダリ/スレーブで重いクエリ(レポートなど)を実行することです。このようにして、プライマリ/マスターは影響を受けず、書き込みと軽い読み取りに役立ちます。

0

セカンダリから読み取ることのほかの別の解決策は、短いドキュメントトランケートが発生するたびに複数回DBから読み取ってから、読み取り操作ごとに短い休憩をとることです。

//some lines below are pseudocode 
function getLocs(callback) { 
    var idList = ...; 
    var index = 0; 
    var maxRead = 1000; 
    var results = []; 

    (function readATrunk(){ 
     TrackingLocation.find({ 
      id: { 
       $in: idList[index]...idList[min(index+maxRead,idList.length-1)] 
      } 
     }). 
     exec(function(error,trunk){ 
      results = results.concat(trunk); 

      if (index+maxRead<idList.length) { 
       index += maxRead; 

       //give a spare 1 second for other queries in 
       //other web pages 
       setTimeout(readATrunk,1000); 
      } 
      else { 
       callback(results); 
      } 
     }); 
    })(); 
} 
関連する問題