Mongo DB-带索引的速度较慢

Mat*_*Die 2 indexing mongodb

我有一个集合中约有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"
                }
            ]
        }
    ],
}
Run Code Online (Sandbox Code Playgroud)

没有索引的搜索

> 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
}
Run Code Online (Sandbox Code Playgroud)

带有索引:

> 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
}
Run Code Online (Sandbox Code Playgroud)

知道为什么索引搜索要比没有索引慢吗?

我也将使用:

db.test1.find({loc:{$ near:[39.876045,32.862245]}})(需要2d索引)

db.test1.find({关键字:{$ in:[“ small”,“ another”]}}))(使用索引作为关键字)

db.test1.find({“ prices.list.name”:/。s。/ })(无需索引,因为我将使用正则表达式)

Asy*_*sky 5

索引允许更快地访问满足查询条件的文档的位置。

在您的示例中,您的查询选择了集合中所有文档的一半。因此,即使索引扫描提供了更快的访问权限来知道哪些文档将与查询谓词相匹配,但它实际上在整体上会产生很多工作。

在集合扫描中,查询将扫描所有文档,并检查查询所依据的字段以查看其是否匹配。一半的时间结束了选择文档。

在索引扫描中,查询将遍历所有索引条目的一半,然后直接从它们跳转到满足查询谓词的文档。根据您的情况,这是更多的操作。

此外,在执行此操作时,当它们需要等待必须将其读取的文档带入RAM时,或者当有等待写入的写操作并且正在显示索引扫描时,这些操作会产生读取互斥锁收率扫描的两倍。如果您的工作集没有足够的RAM,那么添加索引将对现有资源施加更大的压力,并使事情变慢而不是变快。

尝试使用价格相同的查询,而不是价格更大的数字(例如500)(或在数据集中更具选择性的查询)。如果使用索引查询仍然较慢,则可能会在系统上看到很多页面错误。但是,如果有足够的RAM用于索引,则索引查询将快很多,而未索引查询将同样慢。