动态查询性能注意事项
虽然使用动态查询会很方便,但有时会对应用程序性能产生影响。
常规性能注意事项
在动态查询中使用以下元素可能会在一定程度上降低应用程序性能:
- 数据类型转换器和 Java™ 方法
原因:通常,查询操作和谓词将被转换为 SQL,以便数据库服务器能执行它们。但是,如果您的查询包含数据类型转换器(例如,用于 EJB 至 RDB 的映射)或 Java 方法,那么必须在应用程序服务器的内存中执行与查询关联的谓词和操作。
- 为返回 EJB 引用而调用的 EJB 方法和条件
原因:包含这些元素的查询将完全激活应用程序服务器内存中的 EJB。(从查询返回一系列 CMP 字段不会导致激活 EJB。)
当评估应用程序性能时,您还应当注意动态查询是与持久性管理器共享连接的。因此,一个包含 finder 方法、CMR 导航和动态查询的应用程序需要依赖持久性管理器与动态查询服务之间的单个共享连接来执行这些任务。
限制返回集合大小
- 远程接口查询:远程接口的 QueryIterator 类要求在一个方法调用过程期间,使所有查询结果在应用程序服务器内存中具体化。完成该调用时,将关闭用于运行 EJB 查询的 SQL 游标。由于这一要求极有可能造成数据库服务器瓶颈,所以您必须限制任何潜在的大型结果集合的大小。
- 本地接口查询:在大多数情况下,QueryLocalIterator 对象充当 SQL 游标周围的包装器。它由需求驱动;它将导致数据以递增方式返回。对于每个数据库记录检索,必须在迭代器上调用 next() 方法。
但是,在本地接口查询中使用特定的操作将覆盖需求驱动的行为。在这种情况下,查询结果和远程接口查询的结果集合一样在内存中完全具体化。以下是这种情况的一个示例:
select e.myBusinessMethod( ) from EmpBean e where e.salary < 50000 order by 1 desc
这个查询要求执行一个 EJB 方法以生成最终结果集合。因此,必须将数据库中的全部数据集以一个集合的形式返回到应用程序服务器内存中,这样可以在内存中对整个数据集运行 EJB 方法。所以,调用 EJB 方法的本地接口查询操作一般不是需求驱动的。您无法控制此类查询的返回集合大小。
由于所有其他本地接口查询都由需求驱动,因此它们都使您能够控制返回集合的大小。从数据库访存了期望数量的返回值后,您可以在 QueryLocalIterator 对象上使用 close() 方法调用来结束查询循环。否则,用于运行 EJB 查询的 SQL 游标不会关闭,直至整个结果集累积在内存中或事务结束。