【问题标题】:What is the best approach to fetch a flag if objects are connected?如果对象已连接,获取标志的最佳方法是什么?
【发布时间】:2019-06-03 12:39:53
【问题描述】:

假设,我们有两个实体\表 - 用户和游戏(可以是任何东西)。用户可以将多个游戏标记为收藏。所以我们还有一个 user_favourite_game (user_id, game_id) 表。

然后假设,用户正在获取所有可用游戏的列表,其中一些应该具有“最喜欢”标志 = true(使用分页,因此我们假设每次获取 20 个游戏)。所以我在这里看到了两种方法:

  1. 我们可以提出一个填充“收藏夹”字段的请求,例如。 g.
SELECT 
    g.*, 
    ufg.game_id IS NOT NULL AS favourite
FROM
    games g LEFT JOIN
    user_favourite_game ufg ON ufg.user_id = :userId AND g.id = ufg.game_id
ORDER BY
    g.id;
  1. 我们可以选择游戏,然后执行 20 次请求来检查游戏是否是用户的最爱。

哪种方法更好用,为什么?还有其他想法吗?

在上一个项目中,我们使用了第二种方法,因为每个实体所需的计算都很复杂。所以它比上面的例子要复杂得多,而且几乎不可能在单个查询中计算出来。

但总的来说,在我看来,在这种简单的情况下,使用 JOIN 的单个查询应该比 20 个简单查询运行得更快。虽然,我不确定当我们在 user_favourite_game 表中有大量数据时它会如何表现

【问题讨论】:

    标签: sql hibernate web-services request spring-data-jpa


    【解决方案1】:

    将数据库用于其设计用途,并让它作为原始查询的一部分为您提供结果。

    您的数据库在用户喜爱的游戏表上执行外部联接所花费的时间可能会少于 20 次单独请求喜爱标志的网络开销。

    确保随着表格的增长和准确的统计信息,表格被适当地编入索引。

    这不是一个硬性规定,应该以实际的性能测试为指导,但我观察到很多应用程序都受到网络聊天的损害。如果您每个请求的往返成本是 250 毫秒,那么您的 20 次调用将非常昂贵。如果您的往返成本是 1 毫秒,那么人们可能永远不会注意到。

    【讨论】:

    • 谢谢!我一般同意 :) 但也许我没有正确指定:不会有 20 个 HTTP 请求。前端客户端只会发出一次,但后端会向数据库发出 20 次请求。我的意思是查询。是的,我可能应该称它为查询 :)
    • 听起来不错——那就跟着你的鼻子走吧。如果您发现这 20 个请求是即时的,那么这可能不是问题。无论服务器有多近,我仍然会尝试以一种不会对数据库进行 20 次调用的方式进行设计。
    【解决方案2】:

    触发 20 个查询(无论它们多么简单)总是会减慢您的应用程序的速度。因素包括网络成本、查询运行等。

    您应该触发一次查询以获取可用游戏的页面,然后通过传递该页面中存在的游戏的 ID 进行另一次查询以获取该用户的“最喜欢”游戏列表。然后通过循环结果设置/取消设置标志。这样,您只需进行 2 次 DB 调用,就能显着提高性能。

    【讨论】:

    • 谢谢!它完全有意义,可以应用于每个服务调用而无需重写查询)
    • 欢迎您。我可以请点赞并点击“回答”吗:)
    猜你喜欢
    • 2013-08-12
    • 1970-01-01
    • 2011-05-17
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    相关资源
    最近更新 更多