我有一个收藏产品,里面有 ~7.000.000 本书和总共 ~40GB mongodb 3.4 数据库。这是一本书文档的示例:
{
"_id" : ObjectId("597f17d22be7925d9a056e82"),
"ean13" : "9783891491904",
"price" : NumberInt(2100),
"name" : "My cool title",
"author_name" : "Doe, John",
"warengruppe" : "HC",
"book_category_key" : "728",
"keywords": ["fairy tale", "magic", "fantasy"]
...
}
当我用limit查询数据库时,时间是可以的。但是如果我算查询(用于分页),那么它需要很长时间:
2017-08-02T13:03:16.088+0200 I COMMAND [conn74] 命令 mydb.products 命令:count { count: "products", query: { book_category_key: { $in: [ "120", "130", "180", "111", "112", "140", "150", "160", "170", "190", "1AA"] } }, readConcern: {} } planSummary: IXSCAN { book_category_key :1} keysExamined:1129826 docsExamined:1129825 numYields:8851 reslen:44锁:{全局:{acquireCount:{r:17704}},数据库:{acquireCount:{r:8852}},集合:{acquireCount:{r: 8852 } } } 协议(protocol):op_query 7008ms
这里是一个很好的查询:
{
count: "products",
query: {
book_category_key: {
$in: ["120",
"130",
"180",
"111",
"112",
"140",
"150",
"160",
"170",
"190",
"1AA"]
}
}
这需要 7 秒,有时甚至更多(最多 20 秒)。我在 book_category_key 上有一个索引:
{
"v" : 2,
"name" : "book_category_key_1",
"ns" : "mydb.products",
"background" : true
}
最佳答案
问题出在 planSummary: IXSCAN 上。当计数使用 IXSCAN 时,它也会进行 FETCH。像这样:
"planSummary" : "IXSCAN { book_category_key: 1 }",
"execStats" : {
"stage" : "COUNT",
.....
"inputStage" : {
"stage" : "FETCH",
....
"inputStage" : {
"stage" : "IXSCAN",
.....
在您的案例中,它加载了您整个收藏的大约 1/7。
您可以投票给https://jira.mongodb.org/browse/SERVER-17266和相关问题,并使用建议的解决方法强制 COUNT_SCAN:
let cnt = 0;
for(let category of ["120",
"130",
"180",
"111",
"112",
"140",
"150",
"160",
"170",
"190",
"1AA"]) { cnt += db.g.count({book_category_key: category})};
print(cnt);
这是什么
"planSummary" : "COUNT_SCAN { book_category_key: 1 }",
"execStats" : {
"stage" : "COUNT",
...
"inputStage" : {
"stage" : "COUNT_SCAN"
....
对于每个类别,如果索引适合内存,应该快约 10 倍。
关于MongoDB 计数很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45459939/
尝试在我的RoR应用程序中实现计数器缓存列时出现错误Unknownkey(s):counter_cache。我在这个问题中实现了模型关联:Modelassociationquestion这是我的迁移:classAddVideoVotesCountToVideos0Video.reset_column_informationVideo.find(:all).eachdo|p|p.update_attributes:videos_votes_count,p.video_votes.lengthendenddefself.downremove_column:videos,:video_vot
我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']
我有一个数组:array=['Footballs','Baseball','football','Soccer']而且我需要计算看到Football或Baseball的次数,无论大小写和复数形式如何。这是我尝试做的,但没有成功:array.count{|x|x.downcase.include?'football'||x.downcase.include?'baseball'}编写这段代码的正确或更好的方法是什么?我正在寻找3作为答案。 最佳答案 我会将count与一个block结合使用,该block根据与您正在寻找的约束相匹配的正
我正在为在AmazonEC2实例上运行的应用程序设计一个AutoScaling系统。应用程序从SQS读取消息并对其进行处理。AutoScaling系统将监控两件事:SQS中的消息数量,所有EC2机器上运行的进程总数。例如,如果SQS中的消息数量超过3000,我希望系统自动缩放,创建一个新的EC2实例,在其上部署代码,当消息数量低于2000时,我希望系统终止EC2实例.我正在用Ruby和Capistrano做这件事。我的问题是:我无法找到一种方法来确定在所有EC2机器上运行的进程数并将该数字保存在变量中。你能帮帮我吗? 最佳答案 您可
我有以下工厂:FactoryGirl.definedofactory:foodosequence(:name){|n|"Foo#{n}"}trait:ydosequence(:name){|n|"Fooy#{n}"}endendend如果我跑create:foocreate:foocreate:foo,:y我得到Foo1,Foo2,Fooy1。但我想要Foo1,Foo2,Fooy3。我怎样才能做到这一点? 最佳答案 经过smile2day'sanswer的一些提示后和thisanswer,我得出以下解决方案:FactoryGirl.
有人知道为什么我的rails3.0.7cli这么慢吗?当我运行railss或railsg时,他大约需要5秒才能真正执行命令...有什么建议吗?谢谢 最佳答案 更新:我正在将我的建议从rrails切换到rails-sh,因为前者支持REPL,而rrails不是用例。此外,当与ruby环境结合使用时,修补似乎确实可以提高性能变量,现在反射(reflect)在答案中。一个可能的原因可能是这个performancebuginruby每当在ruby代码中使用“require”时,它就会调用一些代码(更多详细信息here)。在使用Rai
简单地说,我如何使用Sequel执行此查询?selecta.id,count(t.id)fromalbumsarightjointrackstont.album_id=a.idgroupbya.id 最佳答案 DB[:albums___a].right_join(:tracks___t,:album_id=>:id).select_group(:a__id).select_more{count(:t__id)} 关于ruby-续集:如何使用分组和计数,我们在StackOverflow上找
我正在测试我的ControllerAction以供练习。在我的Controller中,我只想从我的数据库中按名称获取所有不同的产品:defshop@products=Product.select('distincton(name)*').sort_by&:orderend我已经手动检查过了,它工作正常。现在我正在使用我的RSpec设置我的测试,我想测试@products是一个大于0的数组:RSpec.describePagesController,type::controllerdodescribe'GET#shop'doit'shouldgetallproudcts'doget:sh
我正在尝试计算由二进制形式的1和0的P数表示的数字的数量。如果P=2,则表示的数字为0011、1100、0110、0101、1001、1010,所以计数为6。我试过:[0,0,1,1].permutation.to_a.uniq但这不是大数的最佳解决方案(P可以什么可能是最好的排列技术,或者我们是否有任何直接的数学来做到这一点? 最佳答案 Numberofpermutationcanbecalculatedusingfactorial.a=[0,0,1,1](1..a.size).inject(:*)#=>4!=>24要计算重复项,
我有这段代码:date_counter=Time.mktime(2011,01,01,00,00,00,"+05:00")@weeks=Array.new(date_counter..Time.now).step(1.week)do|week|logger.debug"WEEK:"+week.inspect@weeks从技术上讲,代码有效,输出:SatJan0100:00:00-05002011SatJan0800:00:00-05002011SatJan1500:00:00-05002011etc.但是执行时间完全是垃圾!每周计算大约需要四秒钟。我在这段代码中是否遗漏了一些奇怪的低效