优化MongoDB查询或索引

时间:2012-04-11 12:21:57

标签: optimization mongodb indexing

我正在运行一个非常普通的MongoDB查询,没有什么真正的复杂或特殊的,我想知道它花费的时间(> 1秒)是否正常或我的索引是否有问题。

我为此特定查询提供了一个索引,explain()也告诉我它已被使用,但它每次都会对集合进行全面扫描,并通过>减慢整个网页的速度。 1秒。

查询:

db.tog_artikel.find({"art_filter":{"$exists":false},"$where":"this._id == this.art_hauptartikelnr"})

说明:

> db.tog_artikel.find({"art_filter":{"$exists":false},"$where":"this._id == this.art_hauptartikelnr"}).explain()
{
    "cursor" : "BtreeCursor art_filter_1_art_hauptartikelnr_1",
    "nscanned" : 21306,
    "nscannedObjects" : 21306,
    "n" : 21306,
    "millis" : 1180,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "isMultiKey" : false,
    "indexOnly" : false,
    "indexBounds" : {
        "art_filter" : [
            [
                null,
                null
            ]
        ],
        "art_hauptartikelnr" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ]
    }
}

索引:

{
   "v": 1,
   "key": {
     "art_filter": 1,
     "art_hauptartikelnr": 1 
  },
   "ns": "togshop.tog_artikel",
   "background": true,
   "name": "art_filter_1_art_hauptartikelnr_1" 
}

为什么每次都会扫描整个集合?为什么isMultiKey为false,我如何优化此查询/索引?

环境是一个独立的服务器,MongoDB 2.0.1,64位Linux,可以从PHP w / php-mongo 1.2.6访问

1 个答案:

答案 0 :(得分:7)

  

为什么每次都要扫描整个集合?

不是。它正在通过索引:

"cursor" : "BtreeCursor art_filter_1_art_hauptartikelnr_1",

这意味着索引“art_filter_1_art_hauptartikelnr_1”用于满足$ exists条件。

如果该过滤器不是非常有选择性(即有许多记录满足它),查询仍然会花费很多时间。

  

为什么isMultiKey为false

它是错误的,因为没有使用多键索引。多键索引是包含以数组作为值的字段的索引。它与索引是复合的(即具有多个字段)无关。

 $where":"this._id == this.art_hauptartikelnr"

你的第二个条件是Javascript表达式,这里不能使用索引(因为查询分析器不理解你在做什么)。 即使它确实如此,您也需要一个也包含_id的索引。

  

如何优化此查询/索引?

将您的数据归一化为具有值为true或false的新字段“idIsHauptArtikelNr”。 在(art_filter,idIsHauptArtikelNr)上创建索引,并用

替换您的查询
  { art_filter :{ $exists :false}, idIsHauptArtikelNr : true }