【问题标题】:MongoDB - find query taking a lot of timeMongoDB - 查找查询需要很多时间
【发布时间】:2014-10-14 14:19:53
【问题描述】:

这是 db.mycoll.find({MY_FIELD:"FALSE"}).explain() 返回的内容 -

"cursor" : "BtreeCursor MY_FIELD_1",
"isMultiKey" : false,
"n" : 843392,
"nscannedObjects" : 843392,
"nscanned" : 843392,
"nscannedObjectsAllPlans" : 843392,
"nscannedAllPlans" : 843392,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 17798,
"nChunkSkips" : 0,
"millis" : 636733,
"indexBounds" : {
    "MY_FIELD" : [
        [
            "FALSE",
            "FALSE"
        ]
    ]
},
"server" : "db-2:30000",
"filterSet" : false

这是 db.mycoll.stats() 返回的 -

"ns" : "810.mycoll",
"count" : 1052404,
"size" : 4052704096,
"avgObjSize" : 3850,
"storageSize" : 4841168896,
"numExtents" : 24,
"nindexes" : 5,
"lastExtentSize" : 1257897984,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 1,
"totalIndexSize" : 215903632,
"indexSizes" : {
    "_id_" : 38484432,
    "fieldA_1" : 42155456,
    "fieldB_1_MY_FIELD_1" : 54255936,
    "fieldC_1" : 42343504,
    "MY_FIELD_1" : 38664304
},
"ok" : 1

我的任务是 -

  1. 为什么即使我在 MY_FIELD 上有索引也需要 10 分钟(636 秒)?
  2. 我该如何解决这个问题?无论如何查找需要更少的时间吗?

我知道的东西 -

  1. 此数据库没有争用(读/写)。它总共有大约 100 万份文档。
  2. MY_FIELD 只有两个可能的值

这是 mongostat 数据

insert  query update delete getmore command flushes mapped  vsize    res faults  locked db idx miss %     qr|qw   ar|aw  netIn netOut  conn       time 
    *0      7    436     *0       0     7|0       0   304g   610g  2.12g     40   810:5.6%          0       0|0     3|1   257k   521k    21   20:39:35 
    *0      1    179     *0       0     3|0       0   304g   610g  2.12g     11   810:0.0%          0       0|0     1|1    99k   520k    21   20:39:36 
    *0     *0     53     *0       0     3|0       0   304g   610g  2.12g      3  1273:8.7%          0       1|0     1|1    28k     1m    22   20:39:37 
    *0     *0    805     *0       0     2|0       0   304g   610g  2.12g     44   810:0.0%          0       1|1     2|1   440k   519k    21   20:39:39 
    *0   2966    112     *0       0     1|0       0   304g   610g  2.12g     12   810:2.6%          0       0|0     1|1    63k   518k    21   20:39:40 
    *0      1    398     *0       0     1|0       0   304g   610g  2.12g      9   810:0.0%          0       1|0     1|1   238k   520k    21   20:39:41 
    *0     *0    987     *0       0     1|0       0   304g   610g  2.13g    101   810:0.0%          0       1|2     2|1   612k   518k    21   20:39:42 
    *0     11     86     *0       0    10|0       0   304g   610g  2.13g     17   

【问题讨论】:

  • 索引运行良好,但您在一次查询中返回了超过 800,000 个文档(数据库的 4/5)。限制因素可能是磁盘 I/O 将文档从磁盘读取到内存中,而且 find 对其他操作产生了很多影响。顺便说一句,您将MY_FIELD 存储为字符串,而不是布尔值,尽管您打算将其作为布尔字段。尝试在运行查询时查看 mongostat 并查看是否存在大量页面错误。
  • 真的很有帮助.. 会尝试 mongostat.. 也会使用 limit 和 skip.. 会得到结果..
  • @wdberkeley .. 附加的 mongostat .. 这看起来有很多页面错误.. 因为通常我看到其他小型数据库为 0.. 你认为跳过和限制应该对我有帮助吗? ..我看到限制为 100 会使查询时间缩短“10000”倍
  • 减少您返回的结果数量肯定会有所帮助 - 但您为什么要首先使用一个查询返回 4/5 的数据库?
  • 我必须处理和修改此集合中的每个文档,并将修改后的文档放入另一个集合中。我必须每天这样做一次。。

标签: mongodb


【解决方案1】:

有可能虽然查询使用了索引,但构建文档需要时间。 explain 显示"indexOnly" : false,这意味着该索引不是覆盖索引(请参阅http://docs.mongodb.org/manual/reference/method/cursor.explain)。

你可以试试这个。如果您将查询更改为:

db.mycoll.find( {MY_FIELD: "FALSE"}, {_id: 0, MY_FIELD: 1} ).explain()

那么MY_FIELD 本身的索引可用于构建您的结果。检查这是否运行得更快。显然,这个查询可能对您没有多大用处,因为它不会向您返回文档。这只是为了弄清楚时间是否花在构建文档而不是搜索本身上。

另外,如果MY_FIELD 只有两个值,你最好使用布尔值而不是字符串。文档大小和索引会更小。

【讨论】:

  • 这只是为了弄清楚时间是否花在构建文档而不是搜索本身上>>确实有帮助..我现在使用跳过和限制..
猜你喜欢
  • 2018-01-09
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多