- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我的文档结构是这样的
{
"_id" : "311acd33a0ae8dcc3101246f90af9dc5",
"created_datetime" : ISODate("2013-04-05T10:35:31.143Z"),
"installs" : [
{
"status" : 1,
"app" : "xyz",
"reg_id" : "AVJyaIFI2Q8v93YmOHI5kEOVoCLbd4CAUyVK9zLrC1QCiBcl_bw89i5PvhEuTKmxtb4x130vjMyo78zPI7cedErcRv_Jjn0BN3Wq40hhg",
"last_action_datetime" : ISODate("2013-04-05T10:35:31.143Z"),
"version" : "2"
},
{
"status" : 1,
"app" : "abc",
"reg_id" : "AVJyaIFI2Q8v93YmOHI5kEOVoCLbd4CAUyVK9zLrC1QCiBcl_bw89i5PvhEuTKmxtb4x130vjMyo78zPI7cedErcRv_Jjn0BN3Wq40hhg",
"last_action_datetime" : ISODate("2013-04-05T10:35:31.143Z"),
"version" : "5"
},
{
"status" : 1,
"app" : "pqr",
"last_action_datetime" : ISODate("2013-04-06T10:35:31.143Z"),
"version" : "1"
},
],
"last_update" : ISODate("2013-04-12T06:26:46.333Z"),
"num_updates" : 9,
.....
}
我在 'install.reg_id'
和 'installs.status'
上有一个复合索引,在 'installs.status'
现在我想找到所有文档,其中至少
installs
的一个元素包含 reg_id
并且它的 status
是 1。所以我查询
db.users.find({'installs': {'$elemMatch': {'reg_id': {'$exists': true}, 'status': 1}}}).explain()
我明白了
{
"cursor" : "BtreeCursor installs.status_1",
"isMultiKey" : true,
"n" : 1447034,
"nscannedObjects" : 1720864,
"nscanned" : 1720864,
"nscannedObjectsAllPlans" : 1720864,
"nscannedAllPlans" : 1720864,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 13072,
"nChunkSkips" : 0,
"millis" : 11063,
"indexBounds" : {
"installs.status" : [
[
1,
1
]
]
},
"server" : "####:27017"
}
所以这里应该使用了复合索引,但没有使用。我认为 $elemMatch
是罪魁祸首,所以我做了这个查询
db.users.find({'installs.reg_id': {'$exists': true}}).explain()
我明白了
{
"cursor" : "BasicCursor",
"isMultiKey" : false,
"n" : 2947446,
"nscannedObjects" : 3184871,
"nscanned" : 3184871,
"nscannedObjectsAllPlans" : 3184871,
"nscannedAllPlans" : 3184871,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 23865,
"nChunkSkips" : 0,
"millis" : 16172,
"indexBounds" : {
},
"server" : "####:27017"
}
这表明查询没有使用任何索引。
知道这里出了什么问题吗?
更新:添加提示确实使查询使用索引
db.users.find({'installs': {'$elemMatch': {'reg_id': {'$exists': true}, 'status': 1}}}).hint({"installs.reg_id":1,"installs.status":1}).explain()
返回
{
"cursor" : "BtreeCursor installs.reg_id_1_installs.status_1",
"isMultiKey" : true,
"n" : 1451589,
"nscannedObjects" : 2464985,
"nscanned" : 4373261,
"nscannedObjectsAllPlans" : 2464985,
"nscannedAllPlans" : 4373261,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 20170,
"nChunkSkips" : 0,
"millis" : 106353,
"indexBounds" : {
"installs.reg_id" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
],
"installs.status" : [
[
1,
1
]
]
},
"server" : "####:27017"
}
这里使用复合索引。
最佳答案
没有任何问题。查询优化器正在选择提供更好性能/选择性的索引。
您可以通过“提示”查询使用您希望它使用的索引并比较它需要扫描多少元素和文档以找到它需要返回的元素和文档来确认这一点。
查看您的解释,我可以看到 reg_id 存在于您希望查询使用的索引中超过 92.5% 的索引条目中。这不是很有选择性。使用您希望它使用的索引只会将 3.1M 文档/条目缩小到 2.9M - 不是很好。
它使用 status_1 索引立即将“候选者”缩小到 170 万,现在遍历所有候选者,它发现 140 万有 reg_id。
拥有更多选择性索引是关键,但不要忘记,在这种情况下,您要求它返回 1.4M 文档,因此当需要扫描这么多文档时,很难非常有选择性.
另一件事是相等性,与 {$exists} 相比,这样的索引操作(甚至不相等)更有效。即使是 {$ne:null} 也会比 $exists 更好——一般来说,依靠使用 $exists 或什至不等式的查询来实现像相等性或更小范围的查询(当使用索引时)那样的性能并不是一个好主意.
可在此处找到更多信息:http://docs.mongodb.org/manual/applications/indexes/特别是这里:http://docs.mongodb.org/manual/tutorial/create-queries-that-ensure-selectivity/
关于mongodb 不为 $exists 和 $elemMatch 使用索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16511188/
我在 SQL 查询中使用了一个简单的 IF NOT EXISTS/WHERE NOT EXISTS 语句(我都尝试过),但我总是收到 mysql 错误,不知道为什么。尝试使用不同的引号,检查我的 My
我有 2 个表:tbl1 和 tbl2。我想从 tbl1 返回一行,其中包含以下列:col1、col2、col3、can_be_deleted 、有重要项目。这个想法是,can_be_deleted
如果您是 "t1".persona_1_id = 2,则预期结果应返回 persona_id = 4。 like --- id persona_1_id persona_2_id liked 1 2
我遇到了这个用于执行幂等插入的 github SQL 代码示例。完全按照我想要的方式工作。我不想使用 EXISTS,因为我觉得它有点困惑。可以使用联接对相同的操作进行编码吗? 下面是我在 github
public bool CheckTblExist(string TblName) { try { string cmTxt = "s
表1 Id Name DemoID 1 a 33 2 b 44 3 c 33 4 d 33 5 e 44 表2 Id DemoID IsT
我对 SQL 非常陌生。我想知道当我使用“IF EXISTS”或“IF NOT EXISTS”时会发生什么。例如:以下两个语句有什么区别: 语句 1:(存在) IF EXISTS( SELECT OR
我正在更新 exist-db 集合中的 XML 文件,我必须检查是否存在 id 以决定是否必须在我的文档中替换或插入某些内容。 我注意到随着文件的增长,查询执行时间显着恶化,我决定为我的文件添加一个索
我有一个正在尝试更新的数据库,但我不明白为什么会收到有关不存在的列的奇怪错误。当我使用“heroku pg:psql”访问数据库时,我完全可以看到该列。我找到了couple其他questions遇到类
我有一个这样的查询 SELECT ... FROM ... WHERE (SELECT EXISTS (SELECT...)) which did not return anything th
我有一个可以对数据库执行插入和更新的程序,我从 API 获取数据。这是我得到的示例数据: $uname = $get['userName']; $oname = $get['offerNa
我的批处理文件中有这个脚本 -- if not exist "%JAVA_HOME%" ( echo JAVA_HOME '%JAVA_HOME%' path doesn't exist) -
有没有办法让 Directory.Exists/File.Existssince 区分大小写 Directory.Exists(folderPath) 和 Directory.Exists(folde
考虑使用这两个表和以下查询: SELECT Product. * FROM Product WHERE EXISTS ( SELECT * FROM Codes
我正在使用 Subclipse 1.6.18 使用 Eclipse 3.72 (Indigo) 来处理 SVN 1.6 存储库。这一切都在 Ubuntu 下运行。 我有一个项目,在我更新我的 Ecli
我正在尝试使用 Terraform 配置 Azure 存储帐户和文件共享: resource "random_pet" "prefix" {} provider "azurerm" { versi
我有兴趣为需要使用 NOT EXISTS 的应用程序编写查询。子句来检查一行是否存在。 我正在使用 Sybase,但我想知道一般 SQL 中是否有一个示例,您可以在其中编写具有 NOT EXISTS
我正在尝试使用 Terraform 配置 Azure 存储帐户和文件共享: resource "random_pet" "prefix" {} provider "azurerm" { versi
下面是代码示例: CREATE TABLE #titles( title_id varchar(20), title varchar(80)
我曾经这样编写 EXISTS 检查: IF EXISTS (SELECT * FROM TABLE WHERE Columns=@Filters) BEGIN UPDATE TABLE SET
我是一名优秀的程序员,十分优秀!