深いMongoDBメモリオーバーフローチューニング


MongoDBメモリオーバーフローエラーの説明
exception: getMore runner error: Overflow sort stage buffered data 
usage of 33638076 bytes exceeds internal limit of 33554432 bytes

MongoDBメモリのソートの制限と解決策は、以下から参照されます.https://docs.mongodb.com/manual/reference/method/cursor.sort/#cursor.sortWhen unable to obtain the sort order from an index, MongoDB will sort the results in memory, which requires that the result set being sorted is less than 32 megabytes.When the sort operation consumes more than 32 megabytes, MongoDB returns an error. To avoid this error, either create an index supporting the sort operation (see Sort and Index Use) or use sort() in conjunction with limit() (see Limit Results).MongoDBクエリメソッドの説明と実行順序は、以下から参照されます.https://docs.mongodb.com/manual/tutorial/query-documents/#query-methodQuery MethodMongoDB provides the db.collection.find() method to read documents from a collection. The db.collection.find() method returns a cursor to the matching documents.
db.collection.find(  )

For the db.collection.find() method, you can specify the following optional fields:
  • a query filter to specify which documents to return.
  • a query projection to specifies which fields from the matching documents to return. The projection limits the amount of data that MongoDB returns to the client over the network.

  • You can optionally add a cursor modifier to impose limits, skips, and sort orders. The order of documents returned by a query is not defined unless you specify a sort().以下、https://docs.mongodb.com/manual/reference/method/db.collection.find/#combine-cursor-methodsCombine Cursor MethodsThe following statements chain cursor methods limit() and sort():
    db.bios.find().sort( { name: 1 } ).limit( 5 )
    db.bios.find().limit( 5 ).sort( { name: 1 } )

    The two statements are equivalent; i.e. the order in which you chain the limit() and the sort() methods is not significant. Both statements return the first five documents, as determined by the ascending sort order on ‘name’.ついでにSQL Server文の実行順序「SQL Server 2005技術内幕--照会」という本の冒頭の第1章の第1節を見てみましょう.本の著者も読者にまず文がどのような実行順序であるかを理解させなければならない.クエリの論理実行順序:(1)FROM  (3) < join_type>  JOIN < right_table>   (2) ON < join_condition>  (4) WHERE < where_condition>  (5) GROUP BY < group_by_list>  (6) WITH {cube | rollup} (7) HAVING < having_condition>  (8) SELECT  (9) DISTINCT (11) < top_specification>  < select_list>  (10) ORDER BY < order_by_List>標準のSQLの解析順序は:(1).FROM句は、異なるデータソースからのデータ(2)を組み立てる.WHERE句は、指定する条件に基づいて記録を選別する(3).GROUP BY句は、データを複数のパケット(4)に分割する.集約関数を用いる計算を行う(5).HAVING句を用いるグループ(6)をフィルタリングする.すべての式(7)を計算する.ORDER BYを使用した結果セットのソートの実行順序:1.FROM:FROM句の前の2つのテーブルに対してデカルト積生成仮想テーブルvt 1 2を実行する.ON:vt 1テーブルにONフィルタを適用するのはvt 2 3を挿入するのは本物の行である.OUTER(join):OUTER JOINリザーブテーブル(preserved table)に見つからない行を指定するvt 2生成t 3に行を外部行として追加するfromが2つ以上のテーブルを含む場合、前の結合生成の結果テーブルと次のテーブルに対してステップとステップを繰り返す直接結合4.WHERE:vt 3にWHEREフィルタを適用するにはtrueの行はvt 4 5に挿入されます.GROUP BY:GROUP BY句の列リストからvt 4の行グループに対してvt 5 6を生成する.CUBE|ROLLUP:スーパーグループ(supergroups)をvt 6に挿入するvt 6を生成する.HAVING:vt 6にHAVINGフィルタを適用するにはtrueのグループにvt 7 8を挿入する.SELECT:selectリストを処理するvt 8 9を生成する.DISTINCT:重複行をvt 8から除去するvt 9を生成する.ORDER BY:vt 9の行をorder by句の列リスト順に並べてカーソルvc 10 11を生成する.TOP:vc 10の先頭から指定された数または割合の行を選択してvt 11を生成し、呼び出し元に戻ります.まとめMongoDBとSQL Serverは、先にSELECTリストを作成してから、メモリに並べ替えて、最後に前の行を取ります.メモリオーバーフローの最適化MongoDBクエリ最適化の原則については、Optimize Query Performを参照してください.ancehttps://docs.mongodb.com/manual/tutorial/optimize-query-performance-with-indexes-and-projections/
    データを取り出してプログラムに並べ替える開発もありますが、これはお勧めできません.同じようにメモリが多すぎて、根本的にこの問題を解決していません.
    比較的に推薦する方案は3つあります:1.クエリーとインデックスを最適化します.2.出力列(出力列の数を制限)または行(limit関数など)を減らしたり、入力クエリー_idの数を制限したりします.3.クエリーを2ステップに分け、1ステップ目は出力のみ_id,第2ステップ再通過_id詳細を明らかにする.メモリ内のソートオーバーフローの問題を解決できます.
    バージョン3.0からのシステムパラメータのチューニング
    3.0以降では、パラメータ値を変更することで、メモリのソートサイズの制限を増やすことができます.
    まず、サポートされているすべてのパラメータを見てみましょう.
    use admin
    db.runCommand( { getParameter : 1, "internalQueryExecMaxBlockingSortBytes" : 1 } )

    設定方法を見てみましょう.
    db.adminCommand({setParameter: 1, internalQueryExecMaxBlockingSortBytes: })