ORM使用的优化

Kar*_*och 3 optimization performance orm jpa java-ee

我正在教Java EE,尤其是JPA,Spring和Spring MVC.由于我在大型项目方面没有太多经验,因此很难知道如何向学生介绍ORM的优化.

目前,我提出了一些经典的优化技巧:

  • 准备好的语句(大部分ORM默认使用它们)
  • 第一级和第二级缓存
  • "先写,稍后优化"
  • 可以关闭ORM并将SQL命令直接发送到数据库,以获得非常频繁,专业和昂贵的请求

社区是否还有其他方面可以了解优化ORM的其他方法?我对DAO模式特别感兴趣......

Ale*_*nin 5

从开发人员的角度来看,他必须处理以下优化案例:

  • 减少 ORM和DB之间的干扰.低聊天很重要,因为ORM和数据库之间的每次往返都意味着网络交互,因此其长度至少在0.1到1ms之间变化 - 与查询完整性无关(注意,可能90%的查询通常相当简单).特殊情况是SELECT N + 1问题:如果处理某些查询结果的每一行需要执行额外的查询(因此总共执行1 + count(...)个查询),开发人员必须尝试重写代码这样一种方式可以执行几乎恒定的查询计数.CRUD序列批处理未来查询是优化减少chattines的其他示例(如下所述).
  • 降低查询复杂性.通常ORM在这里很无奈,所以这只是开发人员的头疼.但是,在这种情况下,通常也允许使用允许直接执行SQL命令的API.

所以我可以进行更多的优化:

  • 未来查询:一种API,允许延迟查询的执行,直到其结果必要时为止.如果此时安排了多个未来查询,则它们将作为单个批处理全部执行.因此,这样做的主要好处是减少了往返数据库的数量(=减少ORM和DB之间的干扰).许多ORM实现了这一点,例如NHibernate.
  • CRUD序列批处理:几乎相同,但是当INSERT,UPDATE和DELETE语句被批处理以减少chattines时.同样,由许多ORM工具实现.
  • 结合以上两种情况 - 所谓的"广义批处理".到目前为止,AFAIK只能由DataObjects.Net(我的团队工作的ORM)实现.
  • 异步通用批处理:如果批处理不需要立即答复,则它是异步执行的(当然,与同一会话发送的其他批处理同步,即底层连接无论如何同步使用).当存在大量CRUD语句时带来显着的好处:修改持久实体的代码与DB端操作并行执行.到目前为止,没有ORM实现此优化.

所有这些情况都符合"先写,后优化"规则(或"先表达意图,后来优化").

另一个众所周知的与优化相关的API是预取API(" 预取路径 ").背后的想法是获取预期以最少的查询次数进行处理的对象图(或者更好,在最短的时间内).所以这个API解决了"SELECT N + 1"问题.同样,这部分通常预计会在任何严肃的ORM产品中实施.

从事务隔离的角度来看,所有上述优化都是安全的 - 即它们不会破坏它.从这一点来看,与缓存相关的优化通常是不安全的:您必须仔细配置缓存,以确保在获取实际内容很重要时(例如,在安全检查或某些实时交互时),您将不会获得过时的对象.这里有很多技术,从使用内置缓存开始完成与分布式缓存(memcached等)的集成.任何解决问题的方法都很好; 我个人希望一个开放的API允许将任何我喜欢的缓存集成.

PS我是.NET粉丝,以及DataObjects.NetORMeter.NET开发人员之一.所以我不知道在Java中如何实现完全相似的功能,但我熟悉可用解决方案的范围.