Hi,
There is a requirement to dynamically pick the filter condition from table and then insert the data in another table. I have written the below procedure and it works fine in terms of the result and for small data set. But for large data set , it is taking very long time. How can we optimize it.
Total no of records in temp_tab is approx 52 lakhs
Total no of records in temp_tab_1 is approx 30K
Note that the dynamic insert which is getting created does not take much time to execute. I think issue is with context switching ie. looping the record one by one.
Test data is given below for reference.
CREATE TABLE TEMP_TAB
( "LOCATION_ID" VARCHAR2(1020 BYTE),
"STORE_NAME" VARCHAR2(1020 BYTE),
"STREET_NAME" VARCHAR2(1020 BYTE)
);
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('4346448','АНЮТА','КУРЧАТОВА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('7692143','РОСЬ','СТЕКЛОВСКОГО');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('7691976','СУПЕРМАРКЕТ СТАРТ','НЕЧАЕВА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('37916687','ВИННЫЙ ПОГРЕБОК','ТИМИРЯЗЕВА ');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('37926097','АССОРТИ ПРОДУКТЫ','ПОГРАНИЧНАЯ');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('7710783','ПРОДУКТЫ','ПОКРЫШКИНА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('4310789','АПТЕКА ДЕЖУРНАЯ _ ООО АПТЕКА ДЕЖУРНАЯ','МИРА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('7706784','ПРОДУКТЫ','БОЛЬШАЯ САДОВА');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('4358145','Б/В','ОЛИМПИЙСКИЙ');
Insert into TEMP_TAB (LOCATION_ID,STORE_NAME,STREET_NAME) values ('37926810','ПРОДУКТЫ','ОРЕХОВЫЙ');
CREATE TABLE TEMP_TAB_1
( "ID" VARCHAR2(30 CHAR),
"STORE_ID" NUMBER,
"FILTER_COND" CLOB
) ;
Insert into TEMP_TAB_1 (ID,STORE_ID,FILTER_COND) values ('1',100,' AND (location_id = ''4346448'' or store_name = ''СУПЕРМАРКЕТ СТАРТ'' )');
Insert into TEMP_TAB_1 (ID,STORE_ID,FILTER_COND) values ('1',200,' AND (location_id = ''37916687'' )');
Insert into TEMP_TAB_1 (ID,STORE_ID,FILTER_COND) values ('1',300,' AND (street_name = ''ПОГРАНИЧНАЯ'' )');
Insert into TEMP_TAB_1 (ID,STORE_ID,FILTER_COND) values ('1',400,' AND (street_name = ''ПОКРЫШКИНА'' or location_id = ''37926810'' )');
CREATE TABLE TEST_TABLE
( "LOCATION_ID" VARCHAR2(1020 BYTE),
"ID" VARCHAR2(30 CHAR),
"STORE_ID" VARCHAR2(100 CHAR)
);
CREATE TABLE TEST_error
( "ID" VARCHAR2(30 CHAR),
"STORE_ID" VARCHAR2(100 CHAR),
error varchar2(1000)
);
create or replace PROCEDURE p_test (p_id IN VARCHAR2,
p_temp_tab IN VARCHAR2,
p_temp_tab_1 IN VARCHAR2)
IS
v_sql CLOB;
v_sql_err CLOB;
v_sql_err_cnt VARCHAR2(100 CHAR);
v_upd CLOB;
id VARCHAR2(30 CHAR);
store_id VARCHAR2 (100 CHAR);
filter_cond CLOB;
TYPE c1 IS REF CURSOR;
cur c1;
p_audit_key NUMBER;
v_temp_err_tab VARCHAR2(50 CHAR):='test_error';
v_err_cnt NUMBER;
BEGIN
OPEN cur FOR
'SELECT ID, STORE_ID, filter_cond FROM ' || p_temp_tab_1;
LOOP
FETCH cur INTO id, store_id, filter_cond;
EXIT WHEN cur%NOTFOUND;
v_sql :=
' INSERT INTO test_table '
|| ' ( location_id,ID, STORE_ID )'
|| ' select location_id,'
|| '''' || p_id || '''' || ','
|| '''' || store_id || ''''
|| ' from ' || p_temp_tab
|| ' where 1 = 1 '
|| filter_cond;
dbms_output.put_line(v_sql);
BEGIN
EXECUTE IMMEDIATE v_sql;
EXCEPTION
WHEN OTHERS THEN
v_upd := 'insert into ' || v_temp_err_tab
|| ' select ' || '''' || p_id || '''' || ','
|| '''' || store_id || '''' || ','
|| '''' || 'ERROR' || ''''
|| ' FROM DUAL';
EXECUTE IMMEDIATE v_upd;
END;
END LOOP;
COMMIT;
CLOSE cur;
END p_test;
Procedure call
begin
p_test ('1','temp_tab','temp_tab_1');
end;
/
Any suggestions would be really appreciated.
Thanks.