MongoDB - 索引扫描性能低下

时间:2016-06-24 15:56:09

标签: mongodb

我是MongoDB的新手,我正在尝试测试一些性能,以便了解我的结构是否正常。

我有一个包含5个字段的集合(3个日期,一个Int和一个指向另一个ObjectId的指针)

在这个集合中,我在两个字段上创建了一个索引:

  • _p_monitor_ref Asc(这是指针)
  • 收集的Desc(这是一个日期字段)

索引名称为: _p_monitor_ref_1_collected_-1

我在开头创建了这个索引,并用一些记录填充了表。在那之后,我用这个脚本多次重复记录。

var bulk = db.measurements.initializeUnorderedBulkOp();
db.measurements.find().limit(1483570).forEach(function(document) {
    document._id = new ObjectId();
    bulk.insert(document);
});

bulk.execute();

现在,该系列有300万份文件。

现在,我尝试执行explain以查看集合是否使用索引以及需要执行多少时间。这是查询:

db.measurements.find({ "_p_monitor_ref": "Monitors$iKNoB6Ga5P" }).sort({collected: -1}).explain()

如您所见,我使用_p_monitor_ref按指针搜索所有文档,然后我订购收集-1(这是索引)

这是我运行时的第一个结果。 MongoDB使用索引(BtreeCursor _p_monitor_ref_1_collected_-1),但执行时间非常高"millis" : 120286,

{
    "cursor" : "BtreeCursor _p_monitor_ref_1_collected_-1",
    "isMultiKey" : false,
    "n" : 126862,
    "nscannedObjects" : 126862,
    "nscanned" : 126862,
    "nscannedObjectsAllPlans" : 126862,
    "nscannedAllPlans" : 126862,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 23569,
    "nChunkSkips" : 0,
    "millis" : 120286,
    "indexBounds" : {
        "_p_monitor_ref" : [
            [
                "Monitors$iKNoB6Ga5P",
                "Monitors$iKNoB6Ga5P"
            ]
        ],
        "collected" : [
            [
                {
                    "$maxElement" : 1
                },
                {
                    "$minElement" : 1
                }
            ]
        ]
    },
    "server" : "my-pc",
    "filterSet" : false
}
{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 2967141,
    "nscannedObjects" : 2967141,
    "nscanned" : 2967141,
    "nscannedObjectsAllPlans" : 2967141,
    "nscannedAllPlans" : 2967141,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 27780,
    "nChunkSkips" : 0,
    "millis" : 11501,
    "server" : "my-pc",
    "filterSet" : false
}

现在,如果我再次执行explain,这就是结果,时间是"millis" : 201

{
    "cursor" : "BtreeCursor _p_monitor_ref_1_collected_-1",
    "isMultiKey" : false,
    "n" : 126862,
    "nscannedObjects" : 126862,
    "nscanned" : 126862,
    "nscannedObjectsAllPlans" : 126862,
    "nscannedAllPlans" : 126862,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 991,
    "nChunkSkips" : 0,
    "millis" : 201,
    "indexBounds" : {
        "_p_monitor_ref" : [
            [
                "Monitors$iKNoB6Ga5P",
                "Monitors$iKNoB6Ga5P"
            ]
        ],
        "collected" : [
            [
                {
                    "$maxElement" : 1
                },
                {
                    "$minElement" : 1
                }
            ]
        ]
    },
    "server" : "my-pc",
    "filterSet" : false
}
{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 2967141,
    "nscannedObjects" : 2967141,
    "nscanned" : 2967141,
    "nscannedObjectsAllPlans" : 2967141,
    "nscannedAllPlans" : 2967141,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 23180,
    "nChunkSkips" : 0,
    "millis" : 651,
    "server" : "my-pc",
    "filterSet" : false
}

为什么我有两个非常不同的结果?也许第二次执行会从某种缓存中获取数据......

现在,这个系列有300万的记录......如果这个系列会增长并成为10/20/30万?该怎么办?

我不知道我做错了什么。当然,我正在我的笔记本电脑上执行它(我没有SSD)。

1 个答案:

答案 0 :(得分:1)

你在第二次尝试时执行时间较短的原因与事实相关,即第一次尝试强制mongo将数据加载到内存中,并且在第二次尝试执行时数据仍在内存中可用。

当你的收藏增长时,索引也会增长 - 所以这可能会影响到适应免费内存块的大而且mongodb引擎会加载/卸载该索引的一部分 - 因此性能会有所不同。