简体   繁体   中英

Oracle insert, delete, or updates and table locks

I have a load script that updates my main table with changes every minutes (moving data from a staging table to the prod table).

However, I noticed something. Whenever an insert, update or delete is being done against the prod table, the application reading from the prod table either returns an error for new searches against the database or in the case that it doesn't due to queries against the database being in process already, it's slow.

Is there a way to prevent this from happening? Users are aware of the lag in update times (every 10 mins) and know that a search done now can return different information in another 10 mins (that's acceptable).

Help!

 UPDATE GS_CASE GC
set
(SYSTEM,
  CASE_ID,
  DISPLAY_ID,
  OWNER_FIRSTNAME,
  OWNER_MIDDLENAME,
  OWNER_LASTNAME
) =
(
  SELECT SYSTEM,
  CASE_ID,
  DISPLAY_ID,
  OWNER_FIRSTNAME,
  OWNER_MIDDLENAME,
  OWNER_LASTNAME
FROM GS_STAGING_CASE GSC
where GC.SYSTEM = GSC.SYSTEM
AND GC.CASE_ID = GSC.CASE_ID
AND GSC.ACTION = 'UPDATE'
)
WHERE EXISTS
(
  SELECT NULL 
     FROM GS_STAGING_CASE GSC
     where GC.SYSTEM = GSC.SYSTEM
     AND GC.CASE_ID = GSC.CASE_ID
)
;

--Deletes  
DELETE GS_CASE
 WHERE (SYSTEM, CASE_ID) IN 
 (SELECT GSC.SYSTEM, GSC.CASE_ID 
 FROM GS_CASE GC
 INNER JOIN GS_STAGING_CASE GSC
ON GC.CASE_ID = GSC.CASE_ID
WHERE GC.SYSTEM = GSC.SYSTEM
 AND GSC.ACTION = 'DELETE');

--   select count(1) Into v_count from GS_STAGING_CASE where ACTION = 'INSERT';
--   dbms_output.put_line('Rows in GS_STAGING_CASE = '||v_count);


--Inserts
INSERT
INTO GS_CASE
  (
    SYSTEM,
    CASE_ID,
    DISPLAY_ID,
    OWNER_FIRSTNAME,
    OWNER_MIDDLENAME,
    OWNER_LASTNAME
  )
SELECT GSC.SYSTEM,
  GSC.CASE_ID,
  GSC.DISPLAY_ID,
  GSC.OWNER_FIRSTNAME,
  GSC.OWNER_MIDDLENAME,
  GSC.OWNER_LASTNAME
FROM GS_STAGING_CASE GSC WHERE GSC.ACTION = 'INSERT';

I don't understand well your problem but to do a better job you should try to optimize your process.

In your case the UPDATE is making two useless settings SYSTEM and CASE_ID are equal on both tables by the join condition you don't need to set them again.

But, to do a better job, you could try to convert all the tree instructions into a MERGE witch would be faster as well. This one should do the job.

merge into GS_CASE GC using ( 
        SELECT SYSTEM, CASE_ID, DISPLAY_ID, OWNER_FIRSTNAME, OWNER_MIDDLENAME, OWNER_LASTNAME 
        FROM GS_STAGING_CASE GSC 
        where GC.SYSTEM = GSC.SYSTEM 
            AND GC.CASE_ID = GSC.CASE_ID 
            AND GSC.ACTION in ('UPDATE', 'DELETE', 'INSERT')
    ) GSC on ( GC.SYSTEM = GSC.SYSTEM AND GC.CASE_ID = GSC.CASE_ID AND GSC.ACTION in ('UPDATE','DELETE'))
    when matched then update
        set gc.DISPLAY_ID = gcs.DISPLAY_ID, 
            gc.OWNER_FIRSTNAME = gcs.OWNER_FIRSTNAME,
            gc.OWNER_MIDDLENAME = gcs.OWNER_MIDDLENAME, 
            gc.OWNER_LASTNAME = gcs.OWNER_LASTNAME
        delete
        where gcs.action = 'DELETE'
    when not matched then INSERT(SYSTEM, CASE_ID, DISPLAY_ID, OWNER_FIRSTNAME, OWNER_MIDDLENAME, OWNER_LASTNAME)
        values (gcs.SYSTEM, gcs.CASE_ID, gcs.DISPLAY_ID, gcs.OWNER_FIRSTNAME, gcs.OWNER_MIDDLENAME, gcs.OWNER_LASTNAME)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM