我正在使用MongoDB聚合管道来生成报告。以下是一些快速键信息:
Machine: 8-Core-CPU, 16 GB RAM
OS: Ubuntu 16.04.1 LTS
MongoDB Version: 3.2.11
Mongo PHP Adapter: 1.6.14
PHP Version: 5.6.30
Amount of documents to aggregate: ~ 10+ million
我的聚合管道代码 - 我在PHP中编写和执行 - 看起来像这样:
// create indexes (ASC and DESC for each aggregation key)
$mongoCollection->createIndex('foo' => 1);
$mongoCollection->createIndex('foo' => -1);
$mongoCollection->createIndex('bar' => 1);
$mongoCollection->createIndex('bar' => -1);
// prepare aggregation (1. group, 2. sort)
$aggregationPipeline = [
[
'$group' => [
'_id' => [
'$foo' => 'foo',
'$bar' => 'bar
],
'count' => [
'$sum' => 1
]
]
],
[
'$sort' => [
'count' => -1
]
]
];
// run aggregation
$mongoCollection->aggregate($aggregationPipeline);
问题是:聚合速度不够快!根据我聚合的字段数量(在我的示例中只有2个),该过程大约需要90秒,通常更长。
我的目标是: 提高聚合的性能!
我的问题:
PHP
索引
CPU-芯
拆分
非常感谢您提出任何意见,建议,批评和问题!
答案 0 :(得分:2)
毫无头绪,但我认为它在这里起着非常小的作用。 foo和bar的基数 - 聚合返回的文档/字节数也可能会产生影响。
首先,对于单个字段同时具有升序和降序索引是没有意义的。其次,索引可用于$match
聚合管道,但在进行o $group
操作时无用。所以你的想法是正确的,索引可以帮助你。你正在进行全面扫描。
您无法并行运行聚合操作。您可以通过从外部控制聚合来实现技术,通过将其分解为子任务。但是,既然你正在进行全面扫描 - 再次 - 你的情况并不好。
在同一台计算机上拥有多个分片并通过相同的硬件进行竞争毫无意义。您可以通过使用更多硬件来添加分片。
这里的资源非常有限16 GB RAM和100 M文档。这可能还不够,特别是如果您的文档不是很小并且您必须转到磁盘才能处理更多文档。我会检查聚合期间的IO利用率,以及WiredTiger缓存的行为(假设您使用的是WiredTiger)。
总之,它可能是您有限的资源。客户/驱动程序对慢度的影响可能很小。首先运行并explain()
到聚合,同时观察RAM,磁盘的运行情况。