我正在寻找有关在 MongoDb 3.4 中使用哪种索引策略的建议。
假设我们有一个 people 文档集合,其形状如下:
{
_id: 10,
name: "Bob",
age: 32,
profession: "Hacker"
}
让我们假设一个用于查询集合的 web api 被公开,唯一可能的过滤器是 name 或 age。
对 api 的示例调用类似于:http://myAwesomeWebSite/people?name="Bob"&age=25
这样的调用将在以下查询中翻译:db.people.find({name: "Bob", age: 25})。
为了更好地阐明我们的场景,请考虑:
也就是说,我们必须决定以下哪些索引提供最佳性能:
{name: 1, age: 1}{name: 1} 和 {age: 1}根据一些简单的测试,似乎单个复合索引比两个单字段索引性能要好得多。
通过 mongo shell 执行单个查询,explain() 方法表明使用单个复合索引可以比使用两个单字段索引快近十倍地查询数据库。
在更现实的情况下,这种差异似乎不那么明显,在这种情况下,不是通过 mongo shell 执行单个查询,而是对 nodejs Web 应用程序的两个不同 url 进行多次调用。两个 url 都对数据库执行查询并将获取的数据作为 json 数组返回,一个使用具有单个复合索引的集合,另一个使用具有两个单字段索引的集合(两个集合具有完全相同的文档)。< br/=""> 在本次测试中,单一复合指数在性能方面似乎仍然是最佳选择,但这次差异不那么明显。
根据测试结果,我们正在考虑使用单一复合指数法。
有没有人有这方面的经验?我们是否遗漏了任何重要的考虑因素(可能是大复合索引的一些缺点)?
最佳答案
给定一个在两个字段上具有过滤条件的普通标准查询(没有 limit() 或 sort() 或任何花哨的应用)(如 name 和 age 在您的示例中),为了找到结果文档,MongoDB 将:
age 上的索引,该索引在数百万人的 30 到 40 岁的数据集中 --> 每次查找仍然会产生无穷无尽的文档)。 name 而不是 age,因为与 name(更高的选择性)相比,很多人的 age (选择性如此之低)相同。但该选择还取决于您的具体场景以及您打算对数据库运行的查询。网上有一篇很好的文章,介绍了如何最好地定义复合索引,同时考虑到您的具体情况的各个方面:https://emptysqua.re/blog/optimizing-mongodb-compound-indexes 要考虑的其他方面包括: 索引更新需要付出一定的代价。但是,如果您只关心原始读取速度,并且时不时地只有一些更新,那么您应该选择更多/更大的索引。
最后但并非最不重要的(!)过度使用的底线建议:使用真实数据甚至可能是真实的负载场景来分析您的系统。并且随着您的数据/系统随时间的变化而不断进行测量。
附加内容: https://docs.mongodb.com/manual/core/query-optimization/index.html
Index intersection vs. compound index?
mongodb compund index vs. index intersect
How does the order of compound indexes matter in MongoDB performance-wise?
关于MongoDB查找性能: single compound index VS two single field indexes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47893613/
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
我有一个应用需要发送用户事件邀请。当用户邀请friend(用户)参加事件时,如果尚不存在将用户连接到该事件的新记录,则会创建该记录。我的模型由用户、事件和events_user组成。classEventdefinvite(user_id,*args)user_id.eachdo|u|e=EventsUser.find_or_create_by_event_id_and_user_id(self.id,u)e.save!endendend用法Event.first.invite([1,2,3])我不认为以上是完成我的任务的最有效方法。我设想了一种方法,例如Model.find_or_cr
我想找到给定字符串中的所有匹配项,包括重叠匹配项。我怎样才能实现它?#Example"a-b-c-d".???(/\w-\w/)#=>["a-b","b-c","c-d"]expected#Solutionwithoutoverlappedresults"a-b-c-d".scan(/\w-\w/)#=>["a-b","c-d"],but"b-c"ismissing 最佳答案 在积极的前瞻中使用捕获:"a-b-c-d".scan(/(?=(\w-\w))/).flatten#=>["a-b","b-c","c-d"]参见Rubyde
我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0
我正在寻找一个用ruby演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent
这应该是一个简单的问题,但我找不到任何相关信息。给定一个Ruby中的正则表达式,对于每个匹配项,我需要检索匹配的模式$1、$2,但我还需要匹配位置。我知道=~运算符为我提供了第一个匹配项的位置,而string.scan(/regex/)为我提供了所有匹配模式。如果可能,我需要在同一步骤中获得两个结果。 最佳答案 MatchDatastring.scan(regex)do$1#Patternatfirstposition$2#Patternatsecondposition$~.offset(1)#Startingandendingpo
如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:
我有以下数组:arr=[1,3,2,5,2,4,2,2,4,4,2,2,4,2,1,5]我想要一个包含前三个奇数元素的数组。我知道我可以做到:arr.select(&:odd?).take(3)但我想避免遍历整个数组,而是在找到第三个匹配项后返回。我想出了以下解决方案,我相信它可以满足我的要求:my_arr.each_with_object([])do|el,memo|memo但是有没有更简单/惯用的方法来做到这一点? 最佳答案 使用lazyenumerator与Enumerable#lazy:arr.lazy.select(&:o
假设您有一个可执行文件foo.rb,其库bar.rb的布局如下:/bin/foo.rb/lib/bar.rb在foo.rb的header中放置以下要求以在bar.rb中引入功能:requireFile.dirname(__FILE__)+"../lib/bar.rb"只要对foo.rb的所有调用都是直接的,这就可以正常工作。如果你把$HOME/project和符号链接(symboliclink)foo.rb放入$HOME/usr/bin,然后__FILE__解析为$HOME/usr/bin/foo.rb,因此无法找到bar.rb关于foo.rb的目录名.我意识到像rubygems这