【问题标题】:MongoDB vs MySQL Performance - Simple QueryMongoDB vs MySQL 性能 - 简单查询
【发布时间】:2014-04-06 23:34:53
【问题描述】:

我正在对 mongodb 和 mysql 进行比较,并将 mysql 数据导入 mongodb 集合(>500000 条记录)。 集合如下所示:

{
    "_id" : ObjectId(""),
    "idSequence" : ,
    "TestNumber" : ,
    "TestName" : "",
    "S1" : ,
    "S2" : ,
    "Slottxt" : "",
    "DUT" : ,
    "DUTtxt" : "",
    "DUTver" : "",
    "Voltage" : ,
    "Temperature" : ,
    "Rate" : ,
    "ParamX" : "",
    "ParamY" : "",
    "Result" : ,
    "TimeStart" : new Date(""),
    "TimeStop" : new Date(""),
    "Operator" : "",
    "ErrorNumber" : ,
    "ErrorText" : "",
    "Comments" : "",
    "Pos" : ,
    "SVNURL" : "",
    "SVNRev" : ,
    "Valid" : 
}

比较查询时(均返回 15 条记录):

mysql -> SELECT TestNumber FROM db WHERE Valid=0 AND DUT=68 GROUP BY TestNumber

与

mongodb -> db.results.distinct("TestNumber", {Valid:0, DUT:68}).sort()

结果是等价的,但是从 mongodb 需要 (iro) 17 秒,而从 mysql 需要 0.03 秒。

我理解很难在两种数据库架构之间进行比较,我进一步理解 mongodb 管理员的一项技能是相应地组织数据结构(因此仅导入 mysql 结构不是一个公平的测试) 参考:MySQL vs MongoDB 1000 reads

但是返回差异的时间太长了,不是调优问题。 我的(默认)mongodb 日志文件内容如下:

Wed Mar 05 04:56:36.415 [conn4089] command NTV_Results.$cmd command: { distinct: "results", key: "TestNumber", query: { Valid: 0.0, DUT: 68.0 } } ntoreturn:1 keyUpdates :0 numYields: 6 锁(微) r:21764672 reslen:250 16525ms

我也试过查询:

db.results.group( {
               key: { "TestNumber": 1 },
               cond: {"Valid": 0, "DUT": 68 },
               reduce: function ( curr, result ) { },
               initial: { }
            } )

有了类似(17 秒)的结果,我做错了什么有任何线索吗? 这两项服务都在同一台配备 Windows 7 和 16Gb RAM 的八核 i7 3770 台式电脑上运行。

【问题讨论】:

  • 你在 testnumber 字段上有索引吗?
  • 这些函数都不是您尝试执行的操作类型的好例子,因为它们是旧的实现,被认为被 aggregation pipeline 取代,阅读更多信息跨度>
  • 修复:需要阅读索引的 wrt mongodb。特别是如果导入现有的 mysql 数据库,因为它们可能不会默认创建。

标签: mysql mongodb performance mongodb-query aggregation-framework


【解决方案1】:

性能缓慢的原因可能有很多,其中很多细节过于详细,无法在此详述。但我可以按原样为您提供“入门包”。

在Valid 和DUT 字段上创建Indexes 将改善这些查询和其他查询的结果。使用ensureIndex 命令考虑这种复合形式

db.collection.ensureIndex({ "Valid": 1, "DUT": 1})

对于这些类型的操作,建议使用aggregate:

db.collection.aggregate([
    {$match: { "Valid": 0, "DUT": 68 }},
    {$group: { _id: "$TestNumber" }}
])

应该等同于您所指的 SQL。

有一个SQL to Aggregation Mapping Chart 可以帮助你思考。为了编写有效的查询,还值得熟悉 aggregation operators 的区别。

我多年来一直在为高级任务编写非常复杂的 SQL。而且我发现聚合框架为各种问题解决案例带来了新鲜空气。

值得你花时间学习。

同样值得注意。您的“默认”MongoDB 日志文件正在报告这些操作,因为它们被认为是“慢查询”,然后通过“默认”引起您的注意。您还可以根据需要通过调整database profiler 来查看更多或更少的信息以满足您的需求。

【讨论】:

  • 感谢有关聚合的提示。实际的修复是创建索引。当我导入 mysql 数据库时,没有创建索引。我绝对怀疑我不是第一个(或最后一个)不知道这一点的人。因此,我感谢您的帮助和快速响应。
  • 我不太确定 aggregate{match,group} cmd(特别是对于我的任务),因为我使用的 db.collection.distinct() 现在是最快的 - 这是一种类型聚合 - 我读到了 :) 但你肯定给了我一个加入的向量,所以再次感谢你。
  • @TRxStudio 据说会在答案中创建一个索引,实际上是您的查询专门使用的索引。并且您应该不使用您所展示的组或不同的方法。它们或多或少被认为已弃用。聚合解析全部在本机 C++ 中,并将围绕其他方法运行。因此细节。
猜你喜欢
  • 2015-07-12
  • 1970-01-01
  • 2017-04-28
  • 1970-01-01
  • 2013-06-11
  • 1970-01-01
  • 2017-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多