Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB:查询性能下降_Mongodb_Query Performance - Fatal编程技术网

MongoDB:查询性能下降

MongoDB:查询性能下降,mongodb,query-performance,Mongodb,Query Performance,我在MongoDB有一个用户集合,拥有超过250万条记录,占30 GB。我有大约4到6GB的索引。它位于分片环境中,有两个分片,每个分片由副本集组成。服务器专门用于Mongo,没有任何开销。总RAM超过10GB,足以满足下面所示的查询 我担心的是,尽管有适当字段的索引,但检索结果的时间是巨大的2分钟到惊人的30分钟,这是不可接受的。我是MongoDB的新手&对于为什么会发生这种情况,我真的很困惑 示例架构是: user: { _id: UUID (indexed by default), nam

我在MongoDB有一个用户集合,拥有超过250万条记录,占30 GB。我有大约4到6GB的索引。它位于分片环境中,有两个分片,每个分片由副本集组成。服务器专门用于Mongo,没有任何开销。总RAM超过10GB,足以满足下面所示的查询

我担心的是,尽管有适当字段的索引,但检索结果的时间是巨大的2分钟到惊人的30分钟,这是不可接受的。我是MongoDB的新手&对于为什么会发生这种情况,我真的很困惑

示例架构是:

user:
{
_id: UUID (indexed by default),
name: string,
dob: ISODate,
addr: string,
createdAt: ISODate (indexed),
.
.
.,
transaction:[
{
firstTransaction: ISODate(indexed),
lastTransaction: ISODate(indexed),
amount: float,
product: string (indexed),
.
.
.
},...
],
other sub documents...
}
子文档的长度从0到50不等

我执行的查询包括:

1 db.user.find.min{createdAt:ISODate2014-12-01}.max{createdAt:ISODate2014-12-31}。解释

这个查询一开始运行得很慢,但后来由于热身而被闪电般地快速猜测

2db.user.find{transaction:{$elemMatch:{product:'mobile'}}}。解释

这个查询花了30多分钟&热身并没有帮助,因为每次的表现都是一样的。它归还了一半以上的藏品

3 db.user.find{transaction:{$elemMatch:{product:'mobile'}},firstTransaction:{$in:[ISODate2015-01-01,ISODate2015-01-02]}。解释

这是我想要执行的主要查询。但不幸的是,这个查询需要30多分钟才能执行。我尝试了很多版本,比如:

db.user.find{transaction:{$elemMatch:{product:'mobile'}}}}.min{transaction:{$elemMatch:{firstTransaction:ISODate2015-01-01}}}}}.max{transaction:{$elemMatch:{firstTransaction:ISODate2015-01-02}}。解释

此查询给了我一个错误:

计划员返回错误:找不到最大/最小值的相关索引 带提示的查询(&W):

由于MongoDB中带有$lt、$gt运算符的范围查询的不确定性,我使用了minmax函数,它有时会忽略绑定的任何一个,最终扫描的文档比需要的多

我使用了如下索引:

db.user.ensureIndex({createdAt: 1})

db.user.ensureIndex({"transaction.firstTransaction":1})

db.user.ensureIndex({"transaction.lastTransaction":1})

db.user.ensureIndex({"transaction.product":1})
我尝试对3查询使用复合索引,即:

db.user.ensureIndex{transaction.firstTransaction:1,transaction.product:1}

但这似乎没有给我任何结果。查询被卡住&永远不会返回结果。我是认真的。从不就像僵局一样。我不知道为什么。所以我放弃了这个指数&等待了半个多小时后得到了结果,真是令人沮丧

请帮助我,因为我真的非常渴望找到解决方案&没有想法

此输出可能有助于:

Following is the output for:
查询:

db.user.find({transaction:{$elemMatch:{product:"mobile", firstTransaction:{$gte:ISODate("2015-01-01"), $lt:ISODate("2015-01-02")}}}}).hint("transaction.firstTransaction_1_transaction.product_1").explain()
输出:

{
        "clusteredType" : "ParallelSort",
        "shards" : {
                "test0/mrs00.test.com:27017,mrs01.test.com:27017" : [
                        {
                                "cursor" : "BtreeCursor transaction.product_1_transaction.firstTransaction_1",
                                "isMultiKey" : true,
                                "n" : 622,
                                "nscannedObjects" : 350931,
                                "nscanned" : 352000,
                                "nscannedObjectsAllPlans" : 350931,
                                "nscannedAllPlans" : 352000,
                                "scanAndOrder" : false,
                                "indexOnly" : false,
                                "nYields" : 119503,
                                "nChunkSkips" : 0,
                                "millis" : 375693,
                                "indexBounds" : {
                                        "transaction.product" : [
                                                [
                                                        "mobile",
                                                        "mobile"
                                                ]
                                        ],
                                        "transaction.firstTransaction" : [
                                                [
                                                        true,
                                                        ISODate("2015-01-02T00:00:00Z")
                                                ]
                                        ]
                                },
                                "server" : "ip-12-0-0-31:27017",
                                "filterSet" : false
                        }
                ],
                "test1/mrs10.test.com:27017,mrs11.test.com:27017" : [
                        {
                                "cursor" : "BtreeCursor transaction.product_1_transaction.firstTransaction_1",
                                "isMultiKey" : true,
                                "n" : 547,
                                "nscannedObjects" : 350984,
                                "nscanned" : 352028,
                                "nscannedObjectsAllPlans" : 350984,
                                "nscannedAllPlans" : 352028,
                                "scanAndOrder" : false,
                                "indexOnly" : false,
                                "nYields" : 132669,
                                "nChunkSkips" : 0,
                                "millis" : 891898,
                                "indexBounds" : {
                                        "transaction.product" : [
                                                [
                                                        "mobile",
                                                        "mobile"
                                                ]
                                        ],
                                        "transaction.firstTransaction" : [
                                                [
                                                        true,
                                                        ISODate("2015-01-02T00:00:00Z")
                                                ]
                                        ]
                                },
                                "server" : "ip-12-0-0-34:27017",
                                "filterSet" : false
                        }
                ]
        },
        "cursor" : "BtreeCursor transaction.product_1_transaction.firstTransaction_1",
        "n" : 1169,
        "nChunkSkips" : 0,
        "nYields" : 252172,
        "nscanned" : 704028,
        "nscannedAllPlans" : 704028,
        "nscannedObjects" : 701915,
        "nscannedObjectsAllPlans" : 701915,
        "millisShardTotal" : 1267591,
        "millisShardAvg" : 633795,
        "numQueries" : 2,
        "numShards" : 2,
        "millis" : 891910
}
查询:

db.user.find({transaction:{$elemMatch:{product:'mobile'}}}).explain()
输出:

{
        "clusteredType" : "ParallelSort",
        "shards" : {
                "test0/mrs00.test.com:27017,mrs01.test.com:27017" : [
                        {
                                "cursor" : "BtreeCursor transaction.product_1",
                                "isMultiKey" : true,
                                "n" : 553072,
                                "nscannedObjects" : 553072,
                                "nscanned" : 553072,
                                "nscannedObjectsAllPlans" : 553072,
                                "nscannedAllPlans" : 553072,
                                "scanAndOrder" : false,
                                "indexOnly" : false,
                                "nYields" : 164888,
                                "nChunkSkips" : 0,
                                "millis" : 337909,
                                "indexBounds" : {
                                        "transaction.product" : [
                                                [
                                                        "mobile",
                                                        "mobile"
                                                ]
                                        ]
                                },
                                "server" : "ip-12-0-0-31:27017",
                                "filterSet" : false
                        }
                ],
                "test1/mrs10.test.com:27017,mrs11.test.com:27017" : [
                        {
                                "cursor" : "BtreeCursor transaction.product_1",
                                "isMultiKey" : true,
                                "n" : 554176,
                                "nscannedObjects" : 554176,
                                "nscanned" : 554176,
                                "nscannedObjectsAllPlans" : 554176,
                                "nscannedAllPlans" : 554176,
                                "scanAndOrder" : false,
                                "indexOnly" : false,
                                "nYields" : 107496,
                                "nChunkSkips" : 0,
                                "millis" : 327928,
                                "indexBounds" : {
                                        "transaction.product" : [
                                                [
                                                        "mobile",
                                                        "mobile"
                                                ]
                                        ]
                                },
                                "server" : "ip-12-0-0-34:27017",
                                "filterSet" : false
                        }
                ]
        },
        "cursor" : "BtreeCursor transaction.product_1",
        "n" : 1107248,
        "nChunkSkips" : 0,
        "nYields" : 272384,
        "nscanned" : 1107248,
        "nscannedAllPlans" : 1107248,
        "nscannedObjects" : 1107248,
        "nscannedObjectsAllPlans" : 1107248,
        "millisShardTotal" : 665837,
        "millisShardAvg" : 332918,
        "numQueries" : 2,
        "numShards" : 2,
        "millis" : 337952
}
如果我遗漏了任何细节,请告诉我


谢谢。

1:你的问题太复杂了。经常使用$elemMatch。 第二:如果你能在查询中包含你的切分键,它将大大提高速度

我将为您优化查询:

db.user.find({
     createdAt: {
          $gte: ISODate("2014-12-01"), 
          $lte: ISODate("2014-12-31")
     }
}).explain()

db.user.find({
    'transaction.product':'mobile'
}).explain()

db.user.find({
    'transaction.product':'mobile', 
    firstTransaction:{
       $in:[
           ISODate("2015-01-01"),
           ISODate("2015-01-02")
       ]
    }
}).explain()
底线是:每次都包括你的切分键,这样可以节省时间


甚至可以节省时间来循环使用切分键并多次执行相同的查询。

性能下降的原因是工作集太大。对于某些查询,主要是范围查询,设置超出了物理限制&出现页面错误。由于此原因,性能降低。 我所做的一个解决方案是为查询应用一些过滤器,这将限制结果集&尝试执行相等性检查,而不是在范围上迭代范围。
这些调整对我起了作用。希望它也能帮助其他人。

你知道你的切分键是什么吗?你是想在查询中使用最小值和最大值吗?你知道它们实际上是索引操作符,不是查询操作符,对吗?如果你想使用它们,它们是可以的,但我想我会问,它们的行为与$gt略有不同,$ltMongo从2.6开始就有索引交叉,而且$in比$in更好,或者哪一个是致命的,即使在2.6my shard key is _id.这是UUID类型的用户id。因此,无法在查询中包含shard key,因为这是查询应该返回的内容。我在您的答案中尝试了查询2,但没有结果。对不起,忘了包括那个。另一个问题是点“.”运算符。如果使用它而不是$elemMatch,查询将返回与条件匹配的结果,如OR,而不是AND。这就是我使用$elemMatch的原因。我对$min、$max操作符了解不多。它们的工作原理是否与min、max函数相同?如果不能在读取中包含分片键,则实际上看不到分片对读取操作的任何好处。希望使用随机分布的UUID均匀地分布写操作对您有利。另外,请使用$gte和$lte,而不是$min和$max-您是从哪里想到MongoDB忽略边界和扫描过多文档的?请另外问一个问题,因为有些事情需要澄清。@wdberkeley没有看到切分的任何好处是正确的。我目前正在根据您所在的区域进行切分
用户和服务器。我知道用户访问哪个服务器,并使用该shard键查找用户。这样做时,mongos知道需要搜索哪个碎片。这将查询时间从300-1000毫秒缩短到0-1毫秒。另外,我将答案改为包含$lte和$gte。感谢伯克利和布莱恩·诺亚的帮助。我确实发布了关于最小值和最大值的单独问题,但与索引无关。链接在这里:。如果你能帮助我,我将不胜感激。我在查询时发现了这个问题。在吉拉也有这条线。谢谢
db.user.find({
     createdAt: {
          $gte: ISODate("2014-12-01"), 
          $lte: ISODate("2014-12-31")
     }
}).explain()

db.user.find({
    'transaction.product':'mobile'
}).explain()

db.user.find({
    'transaction.product':'mobile', 
    firstTransaction:{
       $in:[
           ISODate("2015-01-01"),
           ISODate("2015-01-02")
       ]
    }
}).explain()