java - Oracle sql STRUCT 创建花费太多时间

标签 java oracle plsql

Java 导入片段:

import oracle.sql.StructDescriptor;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.STRUCT;

PLSQL 代码片段:

one_user_type :

CREATE OR REPLACE TYPE one_user_type ABCD IS OBJECT
(
   user_id    VARCHAR2(120),
   user_name VARCHAR2(120)
)

Java 代码片段:

//连接conn;

Object[] userObject1 = new Object[] {
                    "101", "peter" };

StructDescriptor userDescriptor = StructDescriptor
                    .createDescriptor("one_user_type", conn);


// The below line takes 2.5 seconds approx to execute.          

STRUCT user1 = new STRUCT(userDescriptor, conn, userObject1);


注释:ojdbc6.jar; jdk1.6、Oracle 11g

问题 - 知道为什么这会花费太多时间,以及如何减少它吗?

编辑 1 以回应@Lalit Kumar B 评论:“太多时间”与实际查询执行有关。创建 STRUCT 是为了将记录表/对象表传递给 PLSQL 过程。实际的查询执行只需要 93 毫秒,当调用两个这样的过程时,UI 等待大约 5 秒,它们都获取对象表和我们需要创建 STRUCT 的地方。 因此 2.5 秒被认为太多了,我喜欢微调它。当我检查其他 Java 对象构造、转换、查询执行等的执行时间时,与这个 STRUCT 创建相比,它们都非常低。 考虑到我真正调用 5 个存储过程(将对象表作为参数)的场景,我进行了 5 个不同的调用来为每个存储过程创建 STRUCT,仅创建 STRUCT 总共需要大约 7 秒。这个想法是调用过程、获取结果、放入包装器并发送回 UI。

编辑 2:[09/20] 为了最大限度地减少时间,创建了一个过程,它采用对象表并充当内部调用 5 个过程的包装器。因此,从 Java 代码来看,它只是一个存储过程调用。尽管如此,必须创建一次 STRUCT 以作为输入提供给包装程序。在多次运行时,它观察到 STRUCT 创建可以在 2 秒到 8 秒之间的任何时间进行!!我在创建 STRUCT 的方式上做错了吗?我从下面提供的链接检查了 Oracle 文档,但我不知道我是否偏离了。

如果您需要更多详细信息,请告诉我。

更新:创建 STRUCT 对象和描述符 http://docs.oracle.com/cd/B12037_01/java.101/b10979/oraoot.htm

编辑 3:附加到解决方案[09/23] 公认的解决方案非常适合存储单个对象。如果要传递对象表,则适用如下情况:

PLSQL:

TYPE one_user_table_type IS TABLE OF one_user_type; // Table of Objects

Java:

UserType user = new UserType( "101", "Peter" );
ArrayDescriptor arrayDescriptor = ArrayDescriptor.createDescriptor(
                    "ONE_USER_TABLE_TYPE", conn);
UserType[] userArray = { user };
Array users = new ARRAY(arrayDescriptor, conn, userArray );
callableStatement.setArray(1, users);

最佳答案

我遇到了同样的情况:STRUCT 构造函数真的很慢,因为 Oracle 查询数据库的属性和完整的依赖链,这不仅是一个单独的数据库调用,这会减慢你的速度,而且还会查询一些系统词典。 这在 JavaDoc 中有些暗示。对于 STRUCT-Constructor,因为约束和有效性是在构造时测试的,这只能通过对整个对象定义的数据库查询来实现。

解决方案是使用自定义 java 类并将值直接流式传输到过程调用中,这将完全消除构造函数时间!

它看起来像这样:

public final class MyUserType implements SQLData
{
    public String userId;
    public String userName;

    public MyUserType(){}

    public MyUserType( final String userId, final String userName )
    {
        this.userId = userId;
        this.userName = userName;
    }

    @Override
    public String getSQLTypeName() throws SQLException
    {
        return "one_user_type";
    }

    @Override
    public void readSQL( final SQLInput stream, final String typeName ) throws SQLException
    {
        userId = stream.readString();
        userName = stream.readString();
    }

    @Override
    public void writeSQL( final SQLOutput stream ) throws SQLException
    {
        stream.writeString( userId );
        stream.writeString( userName );
    }
}

然后你只需使用:

MyUserType param = new MyUserType( "010", "Peter" );
statement.setInputParameter( 1, param );

关于java - Oracle sql STRUCT 创建花费太多时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25916460/

相关文章:

java - 如何在 Windows 中增加 IE 应用程序的堆内存大小?

oracle - 重新编译 Oracle Packages 安全吗

java - 访问 AppEngine 应用程序 ID

java - 读/写期间类文件的魔法值发生变化

oracle - PLSQL_V2_COMPATIBILITY 兼容性

oracle - 在长时间运行的查询期间插入行时会发生什么

sql - Oracle SQL 中最小值但不为 NULL

oracle - 完全用PL/SQL编写大型批处理程序是不是很愚蠢?

oracle - 如何在Oracle中声明和显示变量

java - IntelliJ 14.1 中的 "Reopen Recent Project"操作发生了什么?