0

I have the following PL/SQL block that creates a procedure to insert a new cat:

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;

And the following Java block to batch insert these cats:

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();  

So the issue with this is I can only persist 700 records a second, which is quite slow. I believe the issue is that I invoke the above PL/SQL function once per row (or once per batch entry). How can I re-write the above function to take an array of these statements and do a bulk insert to reduce the number of calls to the function to N modulo 16382 + 1? The database is Oracle 10g.

4

2 回答 2

1

创建数据库对象类型:

CREATE TYPE CAT AS OBJECT(
  AGE NUMBER, WEIGHT NUMBER, NAME VARCHAR2
);

然后创建一个相同的集合类型:

CREATE TYPE CATS IS TABLE OF CAT;

在您的 PL/SQL 过程中接收猫列表并使用FORALL -> 这对性能很重要。

StructDescriptor从 java 中使用and构建您的 CAT 对象和 CATS 集合ArrayDescriptor

于 2012-08-17T14:06:05.877 回答
0

我能够使用以下步骤解决问题:

创建 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。

于 2012-08-17T16:19:40.817 回答