【问题标题】:Getting the column value using Entity getter vs custom SELECT to prevent fetching of additional columns使用实体 getter 与自定义 SELECT 获取列值以防止获取其他列
【发布时间】:2021-02-18 06:34:08
【问题描述】:

这个问题可能有点主观。 假设我有一个 Post 实体,它具有 User 关联。这个User 是实体的所有者。现在我想获取所有者 ID(只是 ID),这是执行此操作的有效方法吗?

  1. post.getUser().getId()
  2. SELECT u.userId from Post p JOIN User u ON p.user.email = u.email where p.id = 1

我发现第二个效率更高,因为我们没有带来额外的列并且只获取必填字段,因此消耗的带宽更少。

这些将在Spring-Data-Jpa@Transactional下执行

【问题讨论】:

  • 能否请您显示您的PostUser 实体映射的相关部分
  • 可能做不到。用户有 12-15 列和帖子 8-10。两者都有 5 个以上的关联,都是 LAZY 获取的(所以这里不用担心)。
  • 您的问题与用户帖子关联有关,因此所有其他列都可以跳过。

标签: hibernate jpa spring-data-jpa


【解决方案1】:

TL;DR: 视情况而定

效率不是主观的,而是定义和上下文的问题。

您需要考虑真正的效率是什么。 你只考虑运行时的效率吗? 或者开发时的效率是否相关? 您的效率与性能/速度相同吗? 或者数据库服务器上的负载是否相关?

在大多数情况下,对于大多数项目而言,开发时间实际上更为相关。大多数代码不在热执行路径上,因此只要性能不差就没有那么重要了。

但我们通常只讨论运行时效率确实很重要的情况,要么是因为我们的服务器负载过重,要么是因为响应时间不令人满意。

因此,一旦您知道自己真正想要和需要什么,您就可以开始衡量/估计这两种方法。同样,您在这些方面付出了多少努力取决于您可能从改进中获得多少。

在进行测量时,请确保您在实际环境中进行测量,这包括通常在相同或并行线程中执行的其他查询也不被考虑在内。

说了这么多:

就其本身而言,专用的 select 语句会更快,并且在 db 服务器、网络和您的应用程序服务器上消耗更少的资源,原因如下:

  • 必须选择更少的数据,很有可能可以从索引加载数据而不是访问表,这可能是实现两个完整对象所必需的。
  • 通过网络传输的数据更少。
  • 不必构造两个完整的对象,只需构造一个基元。由于在设置每个属性时可能会涉及到中间对象的转换和创建,因此这可能会有很大的不同。

但在实际应用程序中,访问帖子和用户完全有可能从一级缓存中得到满足,即对象已经加载到EntityManager 中并且已经完全实现。在这种情况下,从所有合理的指标来看,专用 SQL 语句的效率都会低得多。

【讨论】:

  • “在这种情况下,从所有合理的指标来看,专用 SQL 语句的效率都会低得多” > 是否在此语句后面进行任何负载测试?
【解决方案2】:

您可以在 JPQL 中使用 SELECT NEW 构造,它仅使用您需要的列值来实例化一个对象。见Create new object in SELECT statement

【讨论】:

  • 是的,我知道。但问题是,我们应该使用getter来获取关联的少数字段还是编写Query
  • 绝对是第二个选项。性能很重要。
【解决方案3】:

如果我们将此场景与两个参数进行比较:性能开发工作量,则 Criteria API 查询效率更高。因为……

从 self 表中获取所有列并没有太大区别,但是尽管使用 join fetch 模式或 select fetch 模式从不同的表中使用外键获取显然会影响性能。

  1. 减少样板代码
  2. 我们可以为常用的业务逻辑(即分页、订单等)编写自动化程序,为此我们可以在 @Entity POJO 上使用注释。

此外,ORM 最佳实践需要注意的事项: 尽可能使用FetchType.LAZY,获取关联实体会遇到额外的查询,这会明显降低性能(您可以通过生成用户流量来观察)。 使用@DynamicUpdate@DynamicInsert 进行高效的更新、插入查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 2018-07-16
    • 1970-01-01
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多