为什么MongoDB的性能比MySQL慢?

为什么MongoDB的性能比MySQL慢?,mongodb,mongodb-query,Mongodb,Mongodb Query,我的系统配置:OSx RAM:-8GB,2.5Gz i5 两个数据库表都有1行和相同的数据。我在两个数据库上执行相同的聚合查询 db.temp.aggregate([ { "$match": { ITEMTYPE: 'like' } }, { "$group" : {_id :{ cust_id2: "$ActorID", cust_id: "$ITEMTYPE"}, numberofActorID : {"$sum" : 1}}}, { "$sort": { numb

我的系统配置:OSx RAM:-8GB,2.5Gz i5

两个数据库表都有1行和相同的数据。我在两个数据库上执行相同的聚合查询

db.temp.aggregate([ 
    { "$match": { ITEMTYPE: 'like' } },
    { "$group" : {_id :{ cust_id2: "$ActorID", cust_id: "$ITEMTYPE"}, numberofActorID : {"$sum" : 1}}},
    { "$sort": { numberofActorID: -1 } },
    { "$limit" : 5 }
]); 
我已经创建了覆盖索引

db.temp.ensureIndex( { "ITEMTYPE": 1, "ActorID": 1 } );
“like”的选择性为80%

时间结果是

sqlWithout    sqlWithIndex    mongoWithout       mongoWithIndex
958                 644             3043                  4243
我没有升级MongoDB的系统参数(甚至没有切分) 请告诉我为什么mongoDB很慢,以及如何改进这个问题

{
    "stages" : [
        {
            "$cursor" : {
                "query" : {
                    "ITEMTYPE" : "like"
                },
                "fields" : {
                    "ActorID" : 1,
                    "ITEMTYPE" : 1,
                    "_id" : 0
                },
                "plan" : {
                    "cursor" : "BtreeCursor ",
                    "isMultiKey" : false,
                    "scanAndOrder" : false,
                    "indexBounds" : {
                        "ITEMTYPE" : [
                            [
                                "like",
                                "like"
                            ]
                        ],
                        "ActorID" : [
                            [
                                {
                                    "$minElement" : 1
                                },
                                {
                                    "$maxElement" : 1
                                }
                            ]
                        ]
                    },
                    "allPlans" : [
                        {
                            "cursor" : "BtreeCursor ",
                            "isMultiKey" : false,
                            "scanAndOrder" : false,
                            "indexBounds" : {
                                "ITEMTYPE" : [
                                    [
                                        "like",
                                        "like"
                                    ]
                                ],
                                "ActorID" : [
                                    [
                                        {
                                            "$minElement" : 1
                                        },
                                        {
                                            "$maxElement" : 1
                                        }
                                    ]
                                ]
                            }
                        }
                    ]
                }
            }
        },
        {
            "$group" : {
                "_id" : {
                    "cust_id2" : "$ActorID",
                    "cust_id" : "$ITEMTYPE"
                },
                "numberofActorID" : {
                    "$sum" : {
                        "$const" : 1
                    }
                }
            }
        },
        {
            "$sort" : {
                "sortKey" : {
                    "numberofActorID" : -1
                },
                "limit" : NumberLong(5)
            }
        }
    ],
    "ok" : 1
}
JSON的结构

{ "_id" : ObjectId("5492ba51ff16cd9391a2c02d"), "POSTDBID" : 231041, "ITEMID" : 231041, "ITEMTYPE" : "post", "ITEMCREATIONDATE" : ISODate("2009-02-28T20:37:02Z"), "POSVal" : 0.327282, "NEGVal" : 0.315738, "NEUVal" : 0.356981, "LabelSentiment" : "Neutral", "ActorID" : NumberLong(1179444542), "QuarterLabel" : "2009-1\r", "rowid" : 2 }
注意:为了这个答案,我提到的一些事情被简化了。然而,据我所知,它们可以按所描述的那样应用

误解 首先:聚合不能利用覆盖查询:

即使管道使用索引,聚合仍然需要访问实际文档;i、 e.索引不能完全覆盖聚合管道

(有关详细信息,请参阅。)

第二:聚合并不打算用作实时查询

聚合管道提供了map reduce的替代方案,并且可能是聚合任务的首选解决方案,其中map reduce的复杂性可能是不必要的

您不想使用map/reduce进行实时处理,是吗?;)虽然有时聚合速度非常快,可以用作实时查询,但这并不是预期的目的。如果您愿意,聚合是为了预先计算统计数据

关于聚合的改进 您可能希望在匹配后立即使用
$project
阶段,将传递到组阶段的数据减少到在组阶段处理的数据:

{ $project: { 'ActorID':1, 'ITEMTYPE':1 } }
这可能会改进处理过程

硬件影响 至于你的描述,我想你用的是某种MacBook。OSX和您正在运行的程序需要相当多的RAM。另一方面,MongoDB试图在RAM中保留尽可能多的索引和所谓的工作集(为了保持简单,最近访问的文档)。它就是这样设计的。它应该在一个或多个专用实例上运行。您可能希望使用彩信来检查您是否有大量的页面错误,这是我所期望的。MySQL更为保守,对免费RAM的依赖性也更小,尽管当有一定数量的可用资源时,MySQL的表现会优于MongoDB(从概念上讲,因为这两个DBMS很难进行合理比较),这仅仅是因为MySQL没有针对处理大量可用RAM的情况进行优化。我们甚至不涉及不同进程之间的资源竞争,这也是MongoDB已知的性能杀手

第二,在你有一个旋转磁盘的情况下:MunGDB有各种原因-在旋转磁盘上读性能低于标准,主要问题是寻找延迟。通常,MacBooks中的磁盘转速为5400rpm,这进一步增加了查找延迟,恶化了问题,并使聚合成为真正的难题,如图所示,聚合可以访问大量文档。按照MongoDB存储引擎的工作方式,在索引中相互跟随的两个文档很可能保存在两个完全不同的位置,甚至保存在不同的数据文件中。(这是因为MongoDB进行了大量的写优化,所以在第一个位置写入文档,为文档及其填充提供了足够的空间。)因此,根据集合中文档的数量,可以进行大量的磁盘搜索

另一方面,MySQL是读优化的

数据建模 您没有向我们展示您的数据模型,但有时模型中的微小更改会对性能产生巨大影响。我建议对数据模型进行同行评审

结论
您正在比较两个DBMS,这两个DBMS是针对一个环境中的完全不同的用例而设计和优化的,这个环境与其中一个系统在一个未优化的用例中专门设计的环境几乎相反,它期望从一个非为此而设计的工具中获得实时结果。这可能就是为什么MongoDB优于MySQL的原因。旁注:您没有向我们显示相应的(我的)SQL查询。

您希望得到什么样的答案?MongoDB不是为聚合而构建的。听起来你好像爱上了“NoSQL是神奇的仙尘,可以改善一切”的神话。请告诉我为什么MongoDB索引运行比扫描慢?@philip我知道选择性是个问题,但我使用了覆盖index@user35662要告诉你为什么这个指数会适得其反,你需要。请把它放在你的问题中,而不是评论中。作为注释,它将无法读取。这是sql查询选择ActorID,将(*)计数为numberofActorID from temp,其中ITEMTYPE='like'按ActorID分组按numberofActorID顺序描述限制10" ;首先,我的集合/表中有1000万行。大小mongoDB=9GB,mySQl=2GB。系统在mongoDB测试时使用交换,这对于这种计算机来说是巨大的。现在我只有一百万行可以很容易地放入RAM。如果你需要任何其他信息,请建议我。我应该切分吗?在这个给定的系统上,它是否有助于提高性能?您缺乏硬件和其他方法来比较两者。至于性能改进,请通过编辑您的问题添加数据模型、表格和集合结构。请尽可能好地描述您的用例/业务案例。在MacBook上分片对你没有帮助——你只会加剧资源竞争的问题。如果您有另一台机器,请将其作为独立机器使用。