如何检测“无用”索引?

时间:2015-05-28 13:29:18

标签: mongodb indexing

我有一个包含大量索引的MongoDB集合。

它会为删除几乎没用过的索引带来什么好处吗?

是否有任何方法或工具可以告诉我(数字)索引的使用频率?

编辑:我正在使用2.6.4版

EDIT2:我现在使用的是3.0.3版本

1 个答案:

答案 0 :(得分:2)

是的,所以我就是这样做的。

首先,您需要一个特定集合的所有索引列表(这将按集合进行收集)。我们假设我们正在监视user集合以查看哪些索引无效。

所以我运行db.user.getIndexes(),这会产生一个可解析的JSON输出(你可以从客户端通过command()运行它以及与脚本集成)。

所以你现在有了一个索引列表。这仅仅是了解哪些查询使用哪些索引的情况。如果那个索引没有被击中,你就知道它没用了。

现在,您需要使用explain()从该输出运行每个查询,您可以判断使用哪个索引并将其与getIndexes()中的索引匹配。

所以这是一个示例输出:

> db.user.find({religion:1}).explain()
{
        "queryPlanner" : {
                "plannerVersion" : 1,
                "namespace" : "meetapp.user",
                "indexFilterSet" : false,
                "parsedQuery" : {
                        "religion" : {
                                "$eq" : 1
                        }
                },
                "winningPlan" : {
                        "stage" : "FETCH",
                        "inputStage" : {
                                "stage" : "IXSCAN",
                                "keyPattern" : {
                                        "religion" : NumberLong(1)
                                },
                                "indexName" : "religion_1",
                                "isMultiKey" : false,
                                "direction" : "forward",
                                "indexBounds" : {
                                        "religion" : [
                                                "[1.0, 1.0]"
                                        ]
                                }
                        }
                },
                "rejectedPlans" : [ ]
        },
        "serverInfo" : {
                "host" : "ip-172-30-0-35",
                "port" : 27017,
                "version" : "3.0.0",
                "gitVersion" : "a841fd6394365954886924a35076691b4d149168"
        },
        "ok" : 1
}

queryPlanner字段将使用一组规则,您需要为它们发现和写入,但第一个很简单。

正如您所看到的那样:获胜计划(在winningPlan中)是一个单独的(可能是多次记住,您将需要编码的这些东西)IXSCAN(索引扫描)和关键模式对于使用的索引是:

"keyPattern" : {
    "religion" : NumberLong(1)
},

很好,现在我们可以匹配getIndexes()的关键输出:

    {
            "v" : 1,
            "key" : {
                    "religion" : NumberLong(1)
            },
            "name" : "religion_1",
            "ns" : "meetapp.user"
    },

告诉我们religion索引没有用,实际上是在使用。

不幸的是,这是我能看到的最佳方式。过去,MongoDB有一个索引统计数据,表示索引被击中的次数,但似乎数据已被删除。

因此,您只需为每个集合冲洗并重复此过程,直到删除无用的索引为止。

当然,另一种方法是删除所有索引,然后在测试查询时重新添加索引。如果你确实需要在生产中这样做,那可能会很糟糕。

旁注:解决此问题的最佳方法是根本没有。

通过在我的活动记录中使用索引功能,我可以更轻松地使用它。我经常运行(从PHP)类似的东西:./yii index/rebuild它基本上通过我的活动记录模型,并检测我不再使用哪些索引并从我的应用程序中删除并依次删除它们。当然,它会创建新的索引。