我的基准:
== 数据生成 ==
用大约 350 个字节轻松生成 400 万行(使用 python)。
每个文档都有这些键:
- key1、key2(两个随机列用于测试索引,一个基数为 2000,一个基数为 20)
- longdata:增加每个文档大小的长字符串
- 值:一个简单的数字 (const 10) 来测试聚合
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)
mongo 中的总数据大小约为 6GB。 (在 postgres 中为 2GB)
== 测试 ==
我做了一些测试,但一个足以比较结果:
注意:每次查询后都会重新启动服务器,并清理操作系统缓存,以忽略缓存的影响。
QUERY:用key1=somevalue 聚合所有行(大约200K 行)并为每个key2 求和value
- 映射/减少 10.6 秒
- 聚合 9.7 秒
- 10.3 秒组
查询:
映射/减少:
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'} })
聚合:
db.testtable.aggregate({ $match: {key1: '663969462d2ec0a5fc34'}}, {$group: {_id: '$key2', pop: {$sum: '$value'}} })
组:
db.testtable.group({key: {key2:1}, cond: {key1: '663969462d2ec0a5fc34'}, reduce: function(obj,prev) { prev.csum += obj.value; }, initial: { csum: 0 } })