首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用错误索引的Mongodb

使用错误索引的Mongodb
EN

Stack Overflow用户
提问于 2014-03-19 07:34:11
回答 2查看 2K关注 0票数 2

我对一个集合有多个索引,如下所示。特别是我想要一个查询使用"gTs_1_RE_H_1_l_1",但是查询使用的是"gTs_1"

代码语言:javascript
运行
复制
{
    "0" : {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "ns" : "week_raw_tweet_db.tweets",
        "name" : "_id_"
    },
    "1" : {
        "v" : 1,
        "key" : {
            "gTs" : 1
        },
        "ns" : "week_raw_tweet_db.tweets",
        "name" : "gTs_1",
        "expireAfterSeconds" : 604800
    },
    "2" : {
        "v" : 1,
        "key" : {
            "uN" : 1
        },
        "ns" : "week_raw_tweet_db.tweets",
        "name" : "uN_1"
    },
    "3" : {
        "v" : 1,
        "key" : {
            "gTs" : 1,
            "RE_H" : 1,
            "l" : 1
        },
        "ns" : "week_raw_tweet_db.tweets",
        "name" : "gTs_1_RE_H_1_l_1",
        "background" : 1
    }
}

这里我有一个关于'gTs‘的索引(基于TTL的索引)和一个以'gTs’和'RE_H‘作为前两个键的复合索引。("gTs_1_RE_H_1_l_1")

现在,我正在尝试执行以下查询:

代码语言:javascript
运行
复制
db.tweets.find( {

                    "RE_H" : NumberLong("484001755192636620"),                  
                    "gTs" : {
                        "$lte" : ISODate("2014-03-18T22:00:00Z"),
                        "$gte" : ISODate("2014-03-17T21:00:00Z")
                    }
                }).explain()

据我所知,这应该使用"gTs_1_RE_H_1_l_1",但令人惊讶的是,它使用的是输出中提到的"gTs_1"

代码语言:javascript
运行
复制
{
    "cursor" : "BtreeCursor gTs_1",
    "isMultiKey" : false,
    "n" : 46508,
    "nscannedObjects" : 365746,
    "nscanned" : 365746,
    "nscannedObjectsAllPlans" : 370493,
    "nscannedAllPlans" : 370494,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 1,
    "nChunkSkips" : 0,
    "millis" : 1509,
    "indexBounds" : {
        "gTs" : [ 
            [ 
                ISODate("2014-03-17T21:00:00.000Z"), 
                ISODate("2014-03-18T22:00:00.000Z")
            ]
        ]
    },
    "server" : "Frrole-API1:27017"
}

不管怎么说,如果我给出一个提示,它确实会选择正确的索引。因此,如果我运行以下查询:

代码语言:javascript
运行
复制
db.tweets.find( {

                    "RE_H" : NumberLong("484001755192636620"),                  
                    "gTs" : {
                        "$lte" : ISODate("2014-03-18T22:00:00Z"),
                        "$gte" : ISODate("2014-03-17T21:00:00Z")
                    }
                }).hint("gTs_1_RE_H_1_l_1").explain()

我得到以下输出:

代码语言:javascript
运行
复制
/* 0 */
{
    "cursor" : "BtreeCursor gTs_1_RE_H_1_l_1",
    "isMultiKey" : true,
    "n" : 46508,
    "nscannedObjects" : 233224,
    "nscanned" : 233541,
    "nscannedObjectsAllPlans" : 233224,
    "nscannedAllPlans" : 233541,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 3,
    "nChunkSkips" : 0,
    "millis" : 1874,
    "indexBounds" : {
        "gTs" : [ 
            [ 
                true, 
                ISODate("2014-03-18T22:00:00.000Z")
            ]
        ],
        "RE_H" : [ 
            [ 
                NumberLong(484001755192636620), 
                NumberLong(484001755192636620)
            ]
        ],
        "l" : [ 
            [ 
                {
                    "$minElement" : 1
                }, 
                {
                    "$maxElement" : 1
                }
            ]
        ]
    },
    "server" : "Frrole-API1:27017"
}

有人能帮我理解一下发生了什么事吗!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-19 09:53:54

从输出中可以看到,使用简单索引的查询速度大约为300‘s,这就是mongodb使用该索引的原因。MongoDB的优化并不试图理解查询路径并猜测它的速度,它只是执行不同的查询和度量,其中一个是最快的。您的MongoDB已经了解到使用简单的gTs索引更快。它将通过并行运行不同的查询来不时地自动测试这一点。

据我所知,这应该使用"gTs_1_RE_H_1_l_1",但令人惊讶的是,它使用的是输出中提到的"gTs_1“:

这并不令人惊讶。您应该查看有关索引的文档,特别是关于排序的章节。虽然这里不请求排序,但使用的是range查询($lte及其兄弟姐妹),这非常类似。您至少需要将索引的顺序更改为RE_HgTs,以便首先为equals约束创建索引,然后是范围查询。

票数 2
EN

Stack Overflow用户

发布于 2022-05-08 07:02:00

在选择索引时,定义索引的顺序似乎也很有效,例如:

代码语言:javascript
运行
复制
{
    "0" : {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "ns" : "week_raw_tweet_db.tweets",
        "name" : "_id_"
    },
     "1" : {
        "v" : 1,
        "key" : {
            "gTs" : 1,
            "RE_H" : 1,
            "l" : 1
        },
        "ns" : "week_raw_tweet_db.tweets",
        "name" : "gTs_1_RE_H_1_l_1",
        "background" : 1
    },
    "2" : {
        "v" : 1,
        "key" : {
            "gTs" : 1
        },
        "ns" : "week_raw_tweet_db.tweets",
        "name" : "gTs_1",
        "expireAfterSeconds" : 604800
    },
    "3" : {
        "v" : 1,
        "key" : {
            "uN" : 1
        },
        "ns" : "week_raw_tweet_db.tweets",
        "name" : "uN_1"
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22499148

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档