{code:SQL | title= 0. 테스트용 테이블 빛 인덱스 생성 | borderStyle=solid} CREATE TABLE t1 AS WITH generator AS ( SELECT /*+ materialize */ ROWNUM AS ID FROM all_objects WHERE ROWNUM <= 3000 ) SELECT /*+ ORDERED USE_NL(v2) */ 10000 + ROWNUM ID, TRUNC(DBMS_RANDOM.VALUE(0,5000)) n1, ROWNUM score, RPAD('x',1000) probe_padding FROM generator v1, generator v2 WHERE ROWNUM <= 100000; --> t1 테이블 생성(10만 건) |
ALTER TABLE t1 ADD CONSTRAINT t1_pk PRIMARY KEY(ID); --> id 에 PK 인덱스를 생성함.
EXEC dbms_stats.gather_table_stats(user, 'T1', cascade => true);
|
|{code:SQL|title= 1. Cusor For Loop를 사용한 가장흔하게 볼수있는 PL/SQL 패턴 |borderStyle=solid}
DECLARE
CURSOR c IS
SELECT *
FROM t1
FOR UPDATE;
BEGIN
FOR rec IN c
LOOP
UPDATE /*+ pk_index_test */t1 --> 10만 번 PK 인덱스를 사용하여 UPDATE
SET score = score + 0
WHERE ID = rec.ID;
END LOOP;
COMMIT;
END; --55.24 sec
위 PL/SQL의 ELAPSED TIME은 11.80초이며 이 수치는 10번을 싱행하여 평균값을 취한것.|
{code:SQL | title= 2. SOLUTION | borderStyle=solid} DECLARE CURSOR c IS SELECT * FROM t1 FOR UPDATE; BEGIN FOR rec IN c LOOP UPDATE /*+ current_of_test */ t1 --> 10만 번 current of를 사용하여 UPDATE SET score = score + 0 WHERE CURRENT OF c; END LOOP; |
COMMIT;
END;--45.27 sec
* 위 PL/SQL의 ELAPSED TIME은 10.80초이며 이 수치 또한 10번싱행한 평균값
* PK인덱스를 이용한 UPDATE보다 Current of를사용한 UPDATE가 10%정도 빠름|
|{code:SQL|title= 10%차이 확인 |borderStyle=solid}
SQL> SELECT sql_text
FROM v$sqlarea
WHERE sql_text LIKE '%current_of_test%';
SQL_TEXT
--------------------------------------------------------------------------
UPDATE /*+ current_of_test */ T1 SET SCORE = SCORE + 0 WHERE ROWID = :B1 -->ROWID를 이용하여 Access
| ||
| title= FOR UPDATE가 없는 커서 | borderStyle=solid} DECLARE CURSOR c IS SELECT t1.ROWID, t1.* FROM t1; BEGIN FOR rec IN c LOOP UPDATE /*+ rowid_test */t1 SET score = score + 0 WHERE ROWID = rec.ROWID; END LOOP; |
COMMIT;
END;
|