我正在设计一个API,我想知道哪个查询效率更高?
嵌入式1-n关联:
profile = Profile.where('authenticated_devices.device_token'=> device_token, 'authenticated_devices.access_token'=> access_token).first
或引用的1-n关联:
device = AuthenticatedDevice.where(device_token: device_token, access_token: access_token).first
profile = device.profile
profile.authenticated_device = device
我已经完成了解释,并且在引用的情况下它使用了BtreeCursor,在嵌入的情况下它使用了BasicCursor。添加索引是否可以使嵌入式1-n查询比引用的1-n更快?此查询还有哪些陷阱?如果我想要我的API绝对速度,最好使用嵌入式1-n或引用的1-n?让我们想象这个API也有很重的负担。
更新:
我有这个问题:“引用嵌入的真正决定取决于”相关“数据的数量以及您打算如何访问它。”
答:这是一个非常简单的API。 API加载current_user的Profile,它包含所有信息,基本上每个API调用我都会传递一个设备ID和访问令牌。这是Profile模型中嵌入的信息,我称之为Authenticated Device。它将处于沉重的负荷之下。我正在尝试确定是否应该坚持使用嵌入式1-N并添加索引,或者转移到引用的1-n。所以速度是我最关心的问题。这有帮助吗?
答案 0 :(得分:2)
这里的底线是,对于嵌入式文档以外的任何内容,您必须对数据库进行多个查询。所以在参考情景中你会发现"孩子"在一个请求中,然后在其他请求中访问父项。代码可能会隐藏这一点,但它实际上是数据库的两次往返。
因此嵌入式模型会更快。您目前可能会感到困惑的是,authenticated_devices.device_token
模型和集合中Profile
字段中缺少索引。因此,在索引到位的情况下,这些查找是最佳的。
确实,这里的另一个考虑因素可能是拉动包含所有的"设备"在嵌入式集合中,但只要信息相当轻,它仍然应该比额外的数据库访问产生更少的开销。
最后一点,如果您从Profile
访问的信息实际上非常轻,那么即使它可能违背您的敏感度,最快的可能的方式很可能是只是复制那些信息"每台设备"并在单个请求中使用它,而不是用另一个请求引用另一个文档。
请查看您的使用模式并考虑数据的大小,但通常只要您的使用模式有适当的索引,嵌入式模型应该没有任何问题。