- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有查询(非常慢 ~2,5s):
db.markers.find({ latlng: { '$within': { '$box': [ [ -16, -140 ], [ 75, 140 ] ] } } }).sort({_id: -1}).limit(1000)
当我为这个查询运行 explain 时,我得到了
{
"cursor" : "GeoBrowse-box",
"isMultiKey" : false,
"n" : 1000,
"nscannedObjects" : 242331,
"nscanned" : 242331,
"nscannedObjectsAllPlans" : 242331,
"nscannedAllPlans" : 242331,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 1383,
"nChunkSkips" : 0,
"millis" : 2351,
"indexBounds" : {
"latlng" : [ ]
},
"lookedAt" : NumberLong(262221),
"matchesPerfd" : NumberLong(242331),
"objectsLoaded" : NumberLong(242331),
"pointsLoaded" : NumberLong(0),
"pointsSavedForYield" : NumberLong(0),
"pointsChangedOnYield" : NumberLong(0),
"pointsRemovedOnYield" : NumberLong(0),
"server" : "xx:27017"
}
当我删除 sort({_id: -1}) explain 给我(快速查询 5 milis):
{
"cursor" : "GeoBrowse-box",
"isMultiKey" : false,
"n" : 1000,
"nscannedObjects" : 1000,
"nscanned" : 1000,
"nscannedObjectsAllPlans" : 1000,
"nscannedAllPlans" : 1000,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 5,
"indexBounds" : {
"latlng" : [ ]
},
"lookedAt" : NumberLong(1000),
"matchesPerfd" : NumberLong(1000),
"objectsLoaded" : NumberLong(1000),
"pointsLoaded" : NumberLong(0),
"pointsSavedForYield" : NumberLong(0),
"pointsChangedOnYield" : NumberLong(0),
"pointsRemovedOnYield" : NumberLong(0),
"server" : "xx:27017"
}
我在 latlng 上有 2d 索引,在 _id 和 compound 索引上有 desc 索引。
db.markers.ensureIndex({latlng: '2d', _id:-1})
db.markers.ensureIndex({ latlng: '2d' })
db.markers.ensureIndex({ _id: -1 })
我想要实现的是从最新排序的特定区域获取标记。
有什么想法或建议可以让时间少于 2.5 秒吗??
如果有人想自己做测试
var i = 0,
lat = 0,
lng = 0;
for (i; i < 260000; i++) {
lat = parseFloat(Math.min(-90 + (Math.random() * 180), 90).toFixed(6));
lng = parseFloat(Math.min(-180 + (Math.random() * 360), 180).toFixed(6));
collection.insert({latlng: [lat, lng]}, function () {});
}
collection.find({ latlng: { '$within': { '$box': [ [ -90, -180 ], [ 90, 180 ] ] } } }, {latlng: 1, _id: 1 }).sort({_id: -1}).limit(1000).explain()
在我的本地机器上,我收到(~ 2,6s):
{
"cursor" : "GeoBrowse-box",
"isMultiKey" : false,
"n" : 1000,
"nscannedObjects" : 260000,
"nscanned" : 260000,
"nscannedObjectsAllPlans" : 260000,
"nscannedAllPlans" : 260000,
"scanAndOrder" : true,
"indexOnly" : false,
"nYields" : 1612,
"nChunkSkips" : 0,
"millis" : 2613,
"indexBounds" : {
"latlng" : [ ]
},
"lookedAt" : NumberLong(260000),
"matchesPerfd" : NumberLong(260000),
"objectsLoaded" : NumberLong(260000),
"pointsLoaded" : NumberLong(0),
"pointsSavedForYield" : NumberLong(0),
"pointsChangedOnYield" : NumberLong(0),
"pointsRemovedOnYield" : NumberLong(0),
"server" : "xx:27017"
}
谢谢
最佳答案
您的集合中是否真的定义了以下三个索引?
db.markers.ensureIndex({ latlng: '2d', _id:-1 })
db.markers.ensureIndex({ latlng: '2d' })
db.markers.ensureIndex({ _id: -1 })
geospatial indexing文档建议不要在同一集合上创建多个地理索引。尽管 MongoDB 允许这样做,但这种行为可能并不理想。我对您的情况的猜测是,可能已选择使用非复合 {latlng: '2d'}
而不是复合索引。 explain()
输出在这里并没有真正帮助我们,因为它只是报告 GeoBrowse-box
而不是索引名称;但是,我会建议手动 hinting游标使用复合索引并查看结果是否有所改善。或者,简单地摆脱非复合索引,所以 {latlng: '2d', _id:-1}
因为查询优化器显而易见且唯一的选择。
最后,{_id: -1}
索引是多余的,可以删除。根据 compound index文档,方向仅在处理由多个字段组成的索引时才相关。对于单键索引,我们可以很容易地向后或向前遍历索引。由于 MongoDB 已经默认为我们创建了一个 {_id: 1}
索引,因此简单地依赖它会更有效。
现在,索引不受影响:查询的一个警告是,在按非地理条件(在您的情况下为 _id
)排序之前,限制应用于地理空间查询组件。我相信这意味着,虽然您的结果确实会按 _id
排序,但该排序可能不会考虑匹配范围内的所有文档。 compound index 中提到了这一点文档的一部分,其中引用了 SERVER-4247作为悬而未决的解决方案。
编辑:跟进您的基准
我填充了示例数据,它们是 ±90 到 ±180 之间的 260k 个随机点。然后我运行了您的查询:
db.markers.find(
{ latlng: { $within: { $box: [[-90, -180], [90, 180]] }}},
{ latlng: 1, _id: 1 }
).sort({_id: -1}).limit(1000).explain()
这花费了 1713 毫秒(我将用它作为比较基准,而不是你的 2351 毫秒)。我还会注意到查询匹配了所有 260k 文档,并扫描了相同数量的索引条目。似乎限制在 _id
排序之前没有考虑,这不是我根据注释 here 所期望的。 .然后我稍微调整了查询以检查其他一些情况:
_id
排序和限制的原始查询:nscanned
为 260k,时间为 1470ms。_id
排序的原始查询:nscanned
为 1000,时间为 9ms。nscanned
为260k,时间为2567ms。我还想单独测试未索引字段的排序,以模拟 _id
排序在地理匹配后可能发生的情况;但是,我无法使用 _id
,因为默认索引将始终存在。为此,我删除了复合地理索引,然后按 latlng
对象排序。这导致 260k 的 nscanned
和 1039ms 的时间。如果我加上 1000 的限制,则时间为 461 毫秒。
如果我们将其添加到上面的 1470 毫秒(没有排序和限制的地理查询),它非常接近没有限制的原始查询,即 2567 毫秒。同样,如果我们将 461 毫秒 ( limited sort ) 添加到 1470 毫秒,它接近原始基准测试结果 1713 毫秒。基于这种相关性,我敢打赌您的基准测试中的 _id
排序根本没有利用复合索引。
无论如何,基准测试速度慢的另一个原因是地理匹配范围非常广。更严格的边界肯定会导致更少的数据排序,即使该排序未被索引。也就是说,我确实认为SERVER-4247会对您有所帮助,因为它可能会在执行地理匹配之前先处理非地理排序。
关于performance - 带排序的 MongoDB 地理空间查询 - 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12908871/
运行 Tomcat 失败并出现 java.lang.OutOfMemoryError - 与缺少 PermGen 空间相关的错误。 我最近将 Tomcat 更改为以自己的用户(而非 root)运行。
我们有一个表,其中包含数百万行,其中包含 PostGIS 几何图形。我们要执行的查询是:落在边界几何内的最新条目是什么?这个查询的问题是我们经常会有大量的项目匹配边界框(半径大约为 5 公里),然后
我有一个Elasticsearch设置,它将允许用户搜索通配符作为索引。 array:3 [ "index" => "users" "type" => "user" "body" => arra
我创建了一个表,其中每行包含两个按钮,并且两个按钮连接在一起,我想将两个按钮分开。我用过 不起作用,css 也是,这是他们的另一种方式。 我有另一个问题,因为我不想在表格边框内显示操作按钮,而是在靠近
我试图在 jQuery Mobile 中的两个按钮之间留出空白。现实中的布局是这样的: Button 1 Button 2 (Hidden w/ display: none)
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
您好,我对图表应用程序还很陌生。现在我为我的应用程序创建了条形图。当我运行 create bar chart as separate project 时,输出如下所示。 然后当我将条形图与我的应用程序
我在使用 H2 和 GeoDB(内存中,junit)时遇到问题。 另外,使用 Hibernate 5(每个包的最新版本,包括 hibernate-spatial)和 Spring 4。 通过 id 实
我想画一张澳大利亚的 map ,并将每个城市表示为一个点。 然后突出显示人口众多(> 1M)的城市 library(sp) library(maps) data(canada.cities) head
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 6年前关闭。 Improve this
如何保持.txt文件中存在的空格?在.txt文件中,它表示: text :text text1 :text1 text23 :text2 text345 :text3 如果我写这段
以下哪个键最大? 选项 1:16 个数字 [0,9] 选项 2:30 个元音 选项 3:字母表中的 16 个字母 选项 4:32 位 有人可以帮助我,告诉我哪一个是正确的答案以及我们如何计算它吗?我知
在 Unity 3d 中使用 Azure 空间 anchor 来实现在 iOS 和 Android 上部署的室内和室外增强现实体验是否有益? 最佳答案 是的,对于 Azure Spatial Anch
我有一个绝对定位的圆形图像。图像只需占据屏幕宽度的 17%,并且距离顶部 5 个像素。 问题是,当我调整图像大小以占据屏幕宽度的 17% 时,它会这样做,但同时容器会变长。图像本身不会拉伸(stret
我在 Ubuntu 14.04 上使用 Cassandra。从文档中,我可以看到运行命令: nodetool snapshot 创建我的 key 空间的快照。 命令的输出是: nodetool sn
Heroku引入了“私有(private)空间”,是否可以将现有应用迁移到私有(private)空间? https://blog.heroku.com/archives/2015/9/10/herok
是否允许在语义记录中使用非绑定(bind)空格 或其他 HTML 编码字符?我遇到的问题是 ; 字符被软件视为记录的结尾。 例如:假设我有一份婚姻记录,其中包含 2 个结婚者的姓氏、结婚年份以及结
我正在研究“智能 parking ”项目,偶然发现了包含我们真正需要的YouTube视频。我们已经实现了第一部分,即从视频源进行实时透视变换,下一步是将其定义为一组矩形 我基本上需要知道他是如何做到的
我有两个类:Engine 和 Trainset(多个单元),这两个类共享其 ID 空间,其中包含名称和系列 id=- . 这是我的Engine类(它是抽象的,因为有引擎的子类型(DieselEngin
如果有人能帮助我,那就太好了。 我正在尝试使用Java的Split命令,使用空格分割字符串,但问题是,字符串可能没有空格,这意味着它将只是一个简单的顺序(而不是“输入2”将是“退出”) Scanner
我是一名优秀的程序员,十分优秀!