0

在我们的例子中,休眠 findOne(String id) 花费了很多时间(超过 300 毫秒)。这也不一致。对于某些请求,它会在 100 毫秒内返回结果。

所以我们想提高 findOne 的性能,它不应该花费超过 100 毫秒的时间。由于该表有超过 10 万条记录,我们为选择查询中涉及的实体建立了索引。

我们为每个客户端请求调用这个 findOne 方法。只有 where 子句中的值会改变,而不是其中涉及的列或实体。

所以基本上,如果 Hibernate 可以创建/生成一次选择查询并将其重用于存储库上的所有 findOne 调用,那就太好了。

有人可以帮我弄这个吗?

4

1 回答 1

1

您可以在此处考虑一些优化。

  1. HTTP 会话
  2. 二级缓存
  3. @NamedQuery尽可能使用
  4. 不要使用基于字符串的主键。

HTTP 会话缓存

#findOne当客户端进行身份验证并且值不存在时,您始终可以将使用该方法获取的对象存储在 HTTP 会话中。这将消除对所有后续经过身份验证的请求的查询。您必须考虑的唯一问题是,如果当前用户修改了相关对象,您将希望将会话中的值替换为更新后的副本。

许多 Web 应用程序都使用这种机制。如果您曾经登录您的信用卡或银行的在线帐户系统并打电话给他们更改某些内容,您可能已经注意到您必须注销并重新登录才能看到这些更改。那是同一个概念。

二级缓存

该解决方案甚至适用于使用 Hibernate 的非 HTTP 应用程序。在这种情况下,您有一个位于应用程序端的数据存储,您将其配置为存储不经常更改信息的查询结果。如果条目尚未过期,Hibernate 不会将每个查询的数据库和网络成本用于缓存中存在的内容,而是首先从缓存中进行水合。

2LC 的好处是,如果要缓存它,您可以配置每个查询,您还可以为每个实体类型配置不同的超时和其他配置选项。

@NamedQuery

有时,您执行的复杂查询是以重新解析 JPQL/HQL 为代价的。如果您发现这是一个问题,您可能希望查看是否可以将查询移动到静态@NamedQuery

a 的好处@NamedQuery是,底层解析树的解析、验证和构建在应用程序 boostrap 中完成。这意味着在运行时,Hibernate 只需获取该定义,获取预生成的 SQL,应用参数绑定并将其交给数据库。缺少参数类型验证,开销非常小。

没有基于字符串的键

根据您的数据库平台,基于字符串的主键的性能可能比它们的数字计数器部分差得多,尤其是当您的查询涉及连接时。如果您的字符串字段配置为支持 unicode(例如 NVARCHAR 或 NCHAR 列),那么您的问题就复杂化了。

将字符串用于 a@NaturalId非常好,因为您通常只是针对该字段应用 where 谓词,在该字段中您可以根据查询要求应用各种索引。

但我建议您的查询是否使用基于字符串的主键,将其移至 a@NaturalId并使用基于数字的代理键作为主键。您会注意到您的表连接将显着提高性能,因为它们之间的比较和哈希查找要快得多。

于 2018-05-18T13:04:59.560 回答