我在一个集合中有大约1000000个文档(随机生成)。
示例文档:

{
    "loc": {
        "lat": 39.828475,
        "lon": 116.273542
    },
    "phone": "",
    "keywords": [
        "big",
        "small",
        "biggest",
        "smallest"
    ],
    "prices": [
        {
            "category": "uRgpiamOVTEQ",
            "list": [
                {
                    "price": 29,
                    "name": "ehLYoPpntlil"
                }
            ]
        },
        {
            "category": "ozQNmdwpwhXPnabZ",
            "list": [
                {
                    "price": 96,
                    "name": "ITTaLHf"
                },
                {
                    "price": 88,
                    "name": "MXVgJFBgtwLYk"
                }
            ]
        },
        {
            "category": "EDkfKGZSou",
            "list": [
                {
                    "price": 86,
                    "name": "JluoCLnenOqDllaEX"
                },
                {
                    "price": 35,
                    "name": "HbmgMDfxCOk"
                },
                {
                    "price": 164,
                    "name": "BlrUD"
                },
                {
                    "price": 106,
                    "name": "LOUcsMDeaqVm"
                },
                {
                    "price": 14,
                    "name": "rDkwhN"
                }
            ]
        }
    ],
}

无索引搜索
> db.test1.find({"prices.list.price": { $gt: 190 } }).explain()
{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 541098,
    "nscannedObjects" : 1005584,
    "nscanned" : 1005584,
    "nscannedObjectsAllPlans" : 1005584,
    "nscannedAllPlans" : 1005584,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 8115,
    "nChunkSkips" : 0,
    **"millis" : 13803,**
    "server" : "localhost:27017",
    "filterSet" : false
}

带索引:
> db.test1.ensureIndex({"prices.list.price":1,"menu.list.name":1})
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

> db.test1.find({"prices.list.price": { $gt: 190 } }).explain()
{
    "cursor" : "BtreeCursor prices.list.price_1_prices.list.name_1",
    "isMultiKey" : true,
    "n" : 541098,
    "nscannedObjects" : 541098,
    "nscanned" : 868547,
    "nscannedObjectsAllPlans" : 541098,
    "nscannedAllPlans" : 868547,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 16852,
    "nChunkSkips" : 0,
    **"millis" : 66227,**
    "indexBounds" : {
        "menu.list.price" : [
            [
                190,
                Infinity
            ]
        ],
        "menu.list.name" : [
            [
                {
                    "$minElement" : 1
                },
                {
                    "$maxElement" : 1
                }
            ]
        ]
    },
    "server" : "localhost:27017",
    "filterSet" : false
}

知道为什么索引搜索比没有索引搜索慢吗?
此外,我将使用:
db.test1.find({loc:{$near:[39.876045,32.862245]})(需要2d索引)
db.test1.find({keywords:{$in:[“small”,“another”]})(对关键字使用索引)
db.test1.find({“prices.list.name”:/.s./})(不需要索引,因为我将使用regex)

最佳答案

索引允许更快地访问满足查询的文档位置。
在您的示例中,查询选择集合中所有文档的一半。因此,尽管索引扫描提供了更快的访问来知道哪些文档将匹配查询谓词,但它实际上创建了更多的总体工作。
在集合扫描中,查询将扫描所有文档,并检查要查询的字段以查看是否匹配。有一半的时间最终选择了文档。
在索引扫描中,查询遍历所有索引项的一半,然后从它们直接跳到满足查询谓词的文档。在你的案子里还有更多的行动。
此外,在执行此操作时,当需要等待必须读取的文档被带到ram中时,或者当存在等待进行的写入时,操作将生成读取互斥量,并且索引扫描显示的结果数是集合扫描的两倍。如果您没有足够的内存用于工作集,那么添加索引将给现有资源带来更大的压力,并使事情变得更慢,而不是更快。
使用price与更大的数字(比如500)进行比较(或者在您的数据集中更具选择性)。如果使用索引查询仍然比较慢,那么您可能会在系统上看到许多页面错误。但是,如果有足够的内存用于索引,那么索引查询将快得多,而未索引查询将同样慢。

关于mongodb - Mongodb - 指数较慢,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24714967/

10-09 20:53