db.events.ensureIndex({somefield: 1, timestamp:-1})
我已经确保使用explain查询确实使用了我创建的索引,但性能仍然不够好。
我在想,现在是不是该去sharding了..但是我们很快就会开始每天有大约100万张新唱片在这个收藏中…所以我不确定它是否能很好地扩展..
编辑:查询示例:
> db.audit.find({'userAgent.deviceType': 'MOBILE', 'user.userName': {$in: ['nickey@acme.com']}}).sort({timestamp: -1}).limit(25).explain()
{
"cursor" : "BtreeCursor user.userName_1_timestamp_-1",
"isMultiKey" : false,
"n" : 0,
"nscannedObjects" : 30060,
"nscanned" : 30060,
"nscannedObjectsAllPlans" : 120241,
"nscannedAllPlans" : 120241,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 1,
"nChunkSkips" : 0,
"millis" : 26495,
"indexBounds" : {
"user.userName" : [
[
"nickey@acme.com",
"nickey@acme.com"
]
],
"timestamp" : [
[
{
"$maxElement" : 1
},
{
"$minElement" : 1
}
]
]
},
"server" : "yarin:27017"
}
请注意,deviceType在我的集合中只有2个值。
这是大海捞针。对于那些执行不佳的查询,我们需要explain()
的一些输出。不幸的是,即使这样也只能解决特定查询的问题,所以这里有一个如何解决这个问题的策略:
DB.setprofilinglevel(1,timeout)
,其中timeout
是查询或命令所用的毫秒数的阈值,任何较慢的都将被记录)db.system.profile
中的慢速查询,并使用explain()
explain()
输出中的慢操作,如scanandorder
或大型nscanned
等。一个关键问题是,您显然允许您的用户随意组合过滤器。如果没有索引相交,这将大大增加所需索引的数量。
此外,盲目地向每个可能的查询抛出索引是非常糟糕的策略。构造查询结构并确保索引字段具有足够的选择性是很重要的。
假设您有一个针对所有具有状态
“active”和其他条件的用户的查询。但是在500万用户中,300万活跃,200万不活跃,所以超过500万的条目只有两个不同的值。这样的索引通常没有帮助。最好先搜索其他条件,然后扫描结果。平均而言,当返回100个文档时,您必须扫描167个文档,这不会太严重地损害性能。但事情没那么简单。如果主要标准是用户的joined_at
日期,并且用户随时间停止使用的可能性很高,那么在找到100个匹配项之前,您可能不得不扫描数千个文档。
因此,优化在很大程度上取决于数据(不仅是它的结构,还有数据本身)、内部相关性和查询模式。
如果所有其他方法都失败了,并且如果您确实需要在筛选器中具有如此大的灵活性,那么考虑一个支持索引交叉的单独搜索DB,从那里获取mongo ID,然后使用$in
从mongo获取结果可能是值得的。但这也充满了自身的危险。
--编辑--
你发布的解释是一个关于扫描低选择性场的问题的漂亮例子。显然,“nickey@acme.com”有很多文档。现在,查找这些文档并按时间戳降序排序非常快,因为它得到了高选择性索引的支持。不幸的是,由于只有两种设备类型,mongo需要扫描30060个文档才能找到与“移动”匹配的第一种。
a) ensureIndex({'username': 1, 'userAgent.deviceType' : 1, 'timestamp' :-1})
或
b) ensureIndex({'userAgent.deviceType' : 1, 'username' : 1, 'timestamp' :-1})
不幸的是,这意味着像find({“username”:“foo”}).sort({“timestamp”:-1});
这样的查询不能再使用相同的索引,因此,如上所述,索引的数量将迅速增长。
恐怕目前使用mongodb还没有很好的解决方案。
我试图在mongodb日志文件中只记录慢速查询(执行时间超过10秒)。 我在运行蒙戈作为 并将分析设置为 但是当跟踪日志文件时,它会打印所有的查询。我可以看到很多查询,它的运行时间为0ms。我还需要添加什么来只获得慢速查询吗?
我在mongodb文档中存储图书元数据,如名称、作者、价格、出版商等。我有大约1000万份这些文件,它们都在一个收藏中。平均文档大小为1.9KB。现在我有了关于、和的索引。事实上,我有两个价格指数,一个是升序,一个是降序。我的mongodb版本是2.2.0,我正在使用php驱动程序查询Mongo。驱动程序的版本是1.12。但是当我对price进行范围查询时,我会得到一个。在我的查询中,我试图找到的
我们不敢相信我们在问这个问题<我们如何查询SQLite数据库中的一条记录 假设我们想要id,但只知道表中的名称 这是调用DB的代码 这里是DB乐趣getOneName 这个数据库有一个模型,应用程序有一个适配器 } 我们想输入名称并检索id,但我们甚至无法检索名称<我们已经在Java中多次这样做了,但Kotlin没有成功
我正在开发spring-mvc应用程序。 我需要处理超过10万条数据记录。我不能让它依赖于数据库,所以我必须用java实现所有逻辑。 目前,我正在创建多个线程,并将1000条记录分配给每个要处理的线程。 我正在使用org。springframework。行程安排。同时发生的ThreadPoolTaskExecutor(线程池任务执行器)。 列表项 问题: 建议使用的线程数 我应该在线程之间平均分配
我有一个“Customer”表,它有将近120万条记录,其中一列是ntext类型的“customer_records ”,它包含xml数据。我需要在该列的所有现有记录中替换一个url值。我尝试了下面的替换查询,但是执行该查询需要大约20分钟的时间。 在更新期间,CPU 消耗被利用到最大,这引起了问题。在 120 万条记录中,实际更新的记录中有 60 万条记录,但查询需要读取每条记录以查找和替换 U