MongoDB帯域ソートクエリ異常:Sort operation used more than the maximum 33554432 bytes of RAM


≪データ移行|Data Migration|emdw≫:ユーザーIDに基づいてデータを移行し、ページング・クエリーを作成時間に基づいてソートします.10 W+のデータが同期された後に7.2 w余りしかないことを発見して、しかもほとんどの10 wぐらいのデータ量のユーザーはすべてこのような問題が存在して、ログを探してmongodyが以下のように間違いがあることを発見します:
Caused by: com.mongodb.MongoQueryException: Query failed with error code 96 and error message 'Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.' on server XX.XX.XXX.XX:xxxx
	at com.mongodb.operation.FindOperation$1.call(FindOperation.java:706)
	at com.mongodb.operation.FindOperation$1.call(FindOperation.java:695)
	at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java:462)
	at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java:406)
	at com.mongodb.operation.FindOperation.execute(FindOperation.java:695)
	at com.mongodb.operation.FindOperation.execute(FindOperation.java:83)
	at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:179)
	at com.mongodb.client.internal.MongoIterableImpl.execute(MongoIterableImpl.java:132)
	at com.mongodb.client.internal.MongoIterableImpl.iterator(MongoIterableImpl.java:86)
	at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2667)
	... 12 common frames omitte
Sort operation used more than the maximum 33554432 bytes of RAMの直接翻訳は、ソート操作に使用されるメモリが33554432バイト(32 M)を超えることです.つまり、ソート時にメモリにロードされるデータが多すぎるのは、7 W以上のデータがほとんどの場合に異常が発生している理由を説明しています.ちょうど多くのデータがこんなに多くのメモリを占めているからです.
ソリューションは後で直接提供されました:Add an index, or specify a smaller limit
  • インデックスを追加:なぜメモリソートを使用するかは、インデックスが不足しているため、クエリーしてからメモリをソートする必要があります.公式解釈
    In MongoDB, sort operations can obtain the sort order by retrieving documents based on the ordering in an index. If the query planner cannot obtain the sort order from an index, it will sort the results in memory. Sort operations that use an index often have better performance than those that do not use an index. In addition, sort operations that do not use an index will abort when they use 32 megabytes of memory.
    インデックスがある場合は、インデックス・ソート
  • が使用されます.
  • は、より小さな制限を選択します.つまり、そんなに多くのデータをクエリーしないでください.言い換えれば.すなわち、ソートするデータの範囲を縮小することであり、例えば、より良い分割度のクエリー条件を増加するなど
  • である.
  • もちろんもっとワイルドな方法は私が論理を変えないで、逆にmongodyを変えて、それはソートの使用するメモリを拡大することですが、この方式は公式にエラー情報に書かれていません.ある程度公式が使用を推奨していないことを示しています.そして、この修正の治標は治本しないで、データ量は引き続き増大して、やはり異常が続きます.

  • まとめ:ソートまたはソートフィールドに合理的なインデックスを追加することを推奨します.特に、数が一定の規模の場合(もちろん、数が大きすぎます.下位スライスがない限り、インデックスを追加することは推奨されません)、ソートコストを削減し、クエリー効率を向上させます.