2012-06-10 52 views
2

在调用返回SYS_RECURSOR或调用查询的过程时是否有任何性能改进?从数据库表中获取结果的更好选择

例如

CREATE OR REPLACE PROCEDURE my_proc 
(
    p_id number, 
    emp_cursor IN OUT SYS_REFCURSOR 
) 
AS 
BEGIN 

OPEN emp_cursor for 
select * from emp where emp_number=p_id 
end; 
/

和通过注册OUT参数调用从Java以上,通过IN参数和获取结果。

或者

Java通过

preparedStatement = prepareStatement(connection, "select * from emp where emp_number=?", values); 
resultSet = preparedStatement.executeQuery(); 

哪一个上面是一个更好的选择,从Java调用get从emptable的结果?

回答

1

假设您的prepareStatement方法对所有绑定变量使用适当的类型,没有性能差异。也就是说,您需要确保您正在调用setLong,setDatesetString等,具体取决于参数的数据类型。如果您不正确地绑定数据(即调用setString来绑定数字值),则可能会强制Oracle执行数据类型转换,这可能会阻止优化器使用可提高性能的索引。

但是,从代码组织和维护的角度来看,我宁愿在数据库中而不是Java应用程序中查询。例如,如果您发现某个查询使用的是较差的计划,那么如果该查询位于存储过程中,则与查询嵌入到Java应用程序中相比,DBA可能更容易解决该问题。如果查询存储在数据库中,则还可以使用数据库的依赖关系跟踪功能更轻松地进行影响分析,如果需要执行某些操作,例如确定表格需要更改时会受到什么影响。

+0

从维护和其他角度来看,我认为这是一个好主意,保持存储过程中的查询。 'prepareStatement方法的意思是使用适合所有绑定变量的类型'。能够多解释一下吗?谢谢 – user75ponic

+0

@Polappan - 更新了我的答案。 –

1

那么,我认为从Java调用的角度来看,并没有太大的区别。

一些differencesI能想到的是:

  • 你现在必须保持两个不同的代码库:你的Java代码和存储过程。如果出现错误,您必须在两个不同的地方进行调试,并在两个不同的地方解决问题。
  • 一旦生产就绪,对数据库进行更改可能需要一些额外的形式,除了需要更改部署的Java代码之外。
  • 另一个要考虑的重要问题是数据库独立性,如果您正在构建一个产品以使用不同类型的数据库,则您将被迫编写不同版本的存储过程,并且您将拥有更多的代码来维护(调试,错误修正,更改等)。
  • 如果您打算在不同的(可能还是未知的)客户机的不同环境中部署产品,那么这一点非常重要,因为您无法预测将要使用的RDBMS。
  • 如果你想使用ORM框架,即Hibernate,EclipseLink),它会为你生成相当优化的查询。另外,如果你使用存储过程,稍后集成它会更困难。
  • 通过适当的日志记录功能可以轻松分析查询以实现优化目的。您可以使用JDBC日志记录或ORM提供程序提供的日志记录,并实际查看应用程序使用查询的方式,次数,次数等,并优化它的重要位置。
+0

是的,如果表格结构发生变化,我可能不得不改变两个地方。通过'resultSet.getstring(“emp_name”)'或'resultSet.getstring(2);''获取行是一个好习惯。通过指定'2'作为位置,我们不需要担心'java'中的列名是不是? – user75ponic

+1

@Polappan如果重命名列,则使用整数而不是名称将简化更改,但会使代码在结果集和对象之间的映射中更难理解。另外,如果您重新安排专栏的顺序或者如果您删除专栏,该怎么办?我想说的好处不是那么大。此外,我更新了我的答案,包括其他决定标准。 –

+0

感谢您的解释。 – user75ponic

相关问题