54 votes

Le cadre d’agrégation Mongodb est-il plus rapide que mapper / réduire?

Le cadre d'agrégation introduit dans mongodb 2.2 a-t-il des améliorations de performances particulières par rapport à map / réduire?

Si oui, pourquoi et comment et combien?

(J'ai déjà fait un test pour moi-même et la performance était presque la même)

66voto

Asya Kamsky Points 18076

Tous les test que j'ai personnellement exécuter (y compris à l'aide de vos propres données) montre l'agrégation cadre d'un multiple plus rapide que la carte de réduire, et généralement d'un ordre de grandeur plus rapide.

Prenant seulement 1/10ème des données que vous avez posté (mais plutôt que la compensation cache du système d'exploitation, le réchauffement de la cache d'abord - parce que je veux mesurer la performance de l'agrégation, et pas combien de temps il faut à la page dans les données), j'ai obtenu ceci:

MapReduce: 1,058 ms
L'agrégation Cadre: 133ms

Retrait de l' $match à partir de l'agrégation de cadre et {requête:} mapReduce (parce que les deux auraient suffit d'utiliser un index qui n'est pas ce que nous voulons mesurer) et de regroupement de l'ensemble du jeu de données par cle2 j'ai eu:

MapReduce: 18,803 ms
L'agrégation Cadre: saisie de 1 535 ms

Ceux-ci sont très en ligne avec mes précédentes expériences.

8voto

Taha Jahangir Points 1317

Mon test:

== Génération De Données ==

Générer des 4 millions de lignes (avec python) facile avec environ 350 octets. Chaque document a ces touches:

  • key1, key2 (deux aléatoire colonnes à tester l'indexation, l'un avec la cardinalité de l'an 2000, et une avec la cardinalité de 20)
  • longdata: une longue chaîne pour augmenter la taille de chaque document
  • valeur: un simple nombre (const 10) pour tester l'agrégation


db = Connection('127.0.0.1').test # mongo connection
random.seed(1)
for _ in range(2):
    key1s = [hexlify(os.urandom(10)).decode('ascii') for _ in range(10)]
    key2s = [hexlify(os.urandom(10)).decode('ascii') for _ in range(1000)]
    baddata = 'some long date ' + '*' * 300
    for i in range(2000):
        data_list = [{
                'key1': random.choice(key1s),
                'key2': random.choice(key2s),
                'baddata': baddata,
                'value': 10,
                } for _ in range(1000)]
        for data in data_list:
            db.testtable.save(data)
Taille de données totale était d'environ 6 GO de mongo. (et 2 go dans postgres)

== Tests ==

J'ai fait quelques test, mais un seul suffit pour comparer les résultats:

REMARQUE: le Serveur est redémarré, et le cache du système d'exploitation est nettoyé après chaque requête, d'ignorer l'effet de la mise en cache.

REQUÊTE: ensemble de toutes les lignes avec key1=somevalue (environ 200K lignes) et de la somme value pour chaque key2

  • map/reduce 10.6 sec
  • aggreate 9.7 sec
  • groupe 10.3 sec

requêtes:

map/reduce:

db.testtable.mapReduce(function(){emit(this.key2, this.value);}, function(key, values){var i =0; values.forEach(function(v){i+=v;}); return i; } , {out:{inline: 1}, query: {key1: '663969462d2ec0a5fc34'} })

agrégat:

db.testtable.aggregate({ $match: {key1: '663969462d2ec0a5fc34'}}, {$group: {_id: '$key2', pop: {$sum: '$value'}} })

groupe:

db.testtable.group({key: {key2:1}, cond: {key1: '663969462d2ec0a5fc34'}, reduce: function(obj,prev) { prev.csum += obj.value; }, initial: { csum: 0 } })

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X