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

DBオブジェクトタイプを作成します。

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

次に、同じコレクションタイプを作成します。

CREATE TYPE CATS IS TABLE OF CAT;

PL / SQLプロシージャで、猫のリストを受け取り、FORALL- >を使用します。これはパフォーマンスにとって重要です。

StructDescriptorjavaから、とを使用してCATオブジェクトとCATSコレクションを構築しますArrayDescriptor

于 2012-08-17T14:06:05.877 に答える
0

次の手順で問題を解決できました。

Cat属性を参照するためのOracleオブジェクトの作成:

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;

行(年齢)は、Oracleデータベースで作成した年齢のデータ型を指していることに注意してください。上記を実装することで、完全にインデックス付けされたテーブルへの挿入を1秒あたり約45000に改善することができました。インデックス付けされていないテーブルでは、この値は1秒あたり約70000になります。

于 2012-08-17T16:19:40.817 に答える