转换 PLSQL 函数以处理利用 Oracle ARRAY 的 jdbc 语句
Posted
技术标签:
【中文标题】转换 PLSQL 函数以处理利用 Oracle ARRAY 的 jdbc 语句【英文标题】:Convert PLSQL function to process a jdbc statement that utilizes an Oracle ARRAY 【发布时间】:2012-08-17 13:49:11 【问题描述】:我有以下 PL/SQL 块,它创建了一个插入新猫的过程:
CREATE OR REPLACE PROCEDURE INSERT_NEW_CAT(AGE NUMBER, WEIGHT NUMBER, NAME VARCHAR2)
AS
BEGIN
INSERT INTO CATS(cat_id,age,weight,name)
VALUES(cat_id_sequence.nextval,age,weight,name);
END INSERT_NEW_CAT;
下面的 Java 块可以批量插入这些猫:
CallableStatement statement = conn.prepareCall("CALL insert_new_cat(?,?,?)");
for(int i = 0; i < 50000;i++)
statement.setInt(1, i);
statement.setInt(2,i);
statement.setString(3,"Test");
statement.addBatch();
if(i % 16382== 0) //max value my batch can support on my hardware
statement.executeBatch();
statement.executeBatch();
所以问题是我每秒只能保存 700 条记录,这非常慢。我认为问题在于我每行调用一次上述 PL/SQL 函数(或每批条目一次)。如何重新编写上述函数以获取这些语句的数组并进行批量插入以将函数调用次数减少到 N 模 16382 + 1?数据库是Oracle 10g。
【问题讨论】:
只是一个问题。如果您每 100 条左右的记录执行一次批处理,而不是在 16000 条奇数记录之后执行,您是否认为它可能会更高效? @sethu 我相信对数据库的调用越多,性能就会下降得越多,所以不会。同样作为仅供参考的表演者不是一个词:) 性能肯定是一个词。而且,我更多地来自记忆的角度。内存将被保留,直到您执行批处理。这可能会减慢您的系统速度。您可能需要进行试验并获得正确的批量大小。 @sethu 它绝对不是一个词,不管确定。 与问题无关,但是... english.stackexchange.com/questions/38945/… 【参考方案1】:创建数据库对象类型:
CREATE TYPE CAT AS OBJECT(
AGE NUMBER, WEIGHT NUMBER, NAME VARCHAR2
);
然后创建一个相同的集合类型:
CREATE TYPE CATS IS TABLE OF CAT;
在您的 PL/SQL 过程中接收猫列表并使用 FORALL -> 这对性能很重要。
从 java 中使用 StructDescriptor
和 ArrayDescriptor
构建您的 CAT 对象和 CATS 集合。
【讨论】:
【参考方案2】:我能够使用以下步骤解决问题:
创建 Oracle 对象以引用我的 Cat 属性:
Create Type age is table of number
Create Type weight is table of number
Create Type name is table of varchar(50)
然后在我的 Java 代码中,我执行了以下操作:
ArrayDescriptor ageCollection = ArrayDescriptor.createDescriptor("AGE", conn);
ArrayDescriptor weightCollection = ArrayDescriptor.createDescriptor("WEIGHT", conn);
ArrayDescriptor nameCollection = ArrayDescriptor.createDescriptor("NAME", conn);
int[] ageArray = new int[50000];
int[] weightArray = new int[50000];
String[] nameArray = new String[50000];
for(int i = 0; i <50000;i++)
ageArray[i]=i;
weightArray[i]=i;
nameArray[i] = "Test";
ARRAY oraAge = new ARRAY(ageCollection,conn,ageArray);
ARRAY oraWeight = new ARRAY(weightCollection,conn,weightArray);
ARRAY oraName = new ARRAY(nameCollection,conn,nameArray);
CallableStatement statement = conn.prepareCall("CALL insert_new_cat(?,?,?)";
statement.setObject(1,oraAge);
statement.setObject(2,oraWeight);
statement.setObject(3,oraName);
statement.execute();
conn.commit();
SQL 过程:
CREATE OR REPLACE PROCEDURE INSERT_NEW_CAT (age age, weight weight, name name)
AS
BEGIN
forall i in 1..age.last
insert into cats(id,age,weight,name)
vales(cat_sequence.nextval,age(i),weight(i),name(i);
END INSERT_NEW_CAT;
需要注意的那一行(age age)指的是我在oracle数据库中创建的age的数据类型。通过实现上述内容,我能够将全索引表上的插入提高到每秒约 45000 次。在非索引表上,此值变为每秒 ~70000。
【讨论】:
以上是关于转换 PLSQL 函数以处理利用 Oracle ARRAY 的 jdbc 语句的主要内容,如果未能解决你的问题,请参考以下文章
Oracle-4 - :超级适合初学者的入门级笔记:plsql,基本语法,记录类型,循环,游标,异常处理,存储过程,存储函数,触发器