不include的确速度会快很多,但是感觉这个方法不地道用user的point在于,我以后想拓展user,很容易,不用考虑其他地方的使用,如果直接把部分属性放过去,以后想拓展还是需要考虑数据的升级
没有反馈了?那这种array 的include就不能用了?如果是,你们是否能够给一个官方的说明
你好,这种复杂的数据嵌套,自然会导致查询缓慢,或者取用起来比较复杂,是不鼓励使用的。请在一对多或者多对多的数据关联场景下,多使用 Pointer 或者 AVRelation 来实现。
请参考: https://blog.leancloud.cn/1723/
如果还有疑惑,请随时抛出来。
AVRelation 本质和 Pointer 的数组是一样的,只是有SDK提供的功能会比较容易用。你往上翻翻看之前的聊天记录呢
我还是不明白为啥这么慢Point的效率是O(1),array嵌套也最多是O(n)大家都是工程师,不要臆测,复杂的就一定会特别慢,讲逻辑和实践,对吧再次,我用的是pointer + array,这是很简单的组合使用,真的不复杂
LeanCloud 后端存储是基于 MongoDB 的,MongoDB 自身不提供跨表 join 的功能,include 功能实际上是分多个查询将数据取回的,所以 include 大量数据的时候实际上会发生很多次查询,速度自然会慢。即使是关系型数据库,跨表 join 对性能的影响也是很明显。
去范式化是常用的数据库优化手段,并不是很不地道的用法。
如果一定要实现类似的效果,也不想在数据库中放入冗余数据,可以考虑使用缓存。请看一下我们提供的 LeanCache。
感谢你的回复,我们当前在用LeanCache了我理解你们是用MongoDB的,也理解MongoDB的限制,并不是我不愿意去范式化,而是业务要求我能够提供反查的功能,如果去除pointer,实现起来的逻辑会比较复杂且不可维护(当然当前的实现也确实存在一些问题,再考虑替换成AVRelation,但是之前你说AVRelation和现在的本质是一样的)
我觉得query的算法是可以优化下的以我之前给你的那个例子,query一次,大概include了500个Pointer,耗时约8s,单纯从数据上看,这个效率还是挺差的,我想你赞同吧实际上mongodb是支持批量获取所有的_id,而且性能不差(基础功能),如果一次查询500个pointer,时间肯定可以控制在毫秒我不清楚,如果使用AVRelation是否是一样的效果呢?
你可以去掉 query.include('post.likes'); 看看差距,问题可能在这。
首先谢谢你的回复,已经知道是这个性能的问题只是现在在讨论,是我们修改应用,重新考虑实现方式,还是由你们来优化查询
和 @dennis 讨论了一下,你这个场景有两个解决办法:1,Post 中保存 likes 信息,不使用 pointer Array,而是该用我们的 relation。因为 Array 我们不知道具体的类型(Array 里面可以存 pointer, 也可以存自定义的 JSON),所以后端做查询的时候是一个一个来的。这样,如果 Status 有M条,可能对应 M 个 Post,但是每个 Post 对应 N(N比M大得多)个 likes,后端为了获取 likes,会做 M *N 次查询。如果你把 Array 换成 Relation,我们自己是知道里面存的都是 pointer 的,所以我们可以只通过一次查询得到多个 likes。当然,这个代价就是需要在客户端这边在做一次 getRelation 的查询,也就是说可能会多做 M 次查询,不过这个代价应该会远低于 M*N 次查询。2,使用数据冗余来做,在 likes 里面不要保存 pointer,直接把保存 object、avatar、nickname 这样的JSON object,足够你显示就可以了,这样查询起来是最快的,当然,数据同步存在一些问题,就看产品层面能否容忍。现在我们能想到的就是这两种办法,你可以考虑一下。
多谢jfeng我们后续切换成AVRelation