레이블이 오라클인 게시물을 표시합니다. 모든 게시물 표시
레이블이 오라클인 게시물을 표시합니다. 모든 게시물 표시

2013년 10월 23일 수요일

오라클 테이블 단편화(행이행, 행연쇄) 체크 (Oracle Table chain )

오라클 테이블 단편화(행이행, 행연쇄) 체크 (Oracle Table chain )



블록사이즈가 4K인데 레코드의 한행이 4K이상이라면 여러 블럭에 나누어 저장되게 되는데 이를
행연쇄 라고 하구요, 처음 insert문에서 입력되는 데이터는 작았는데 추후 많은 량의 데이터로 update
하게되어 해당 불록에 다 기록할 수 없어 다른 블록에 기록할 수 있는 데 이를 행이동 이라고 합니다.

행이행의 경우 원래의 블록에 새로운 블록을 가리키는 포인터를 두며 갱신전 데이터가 있는 영역은 사용하지 못하게 됩니다. 이 처럼 재이용되지 못하는 영역이 생기는 것을 단편화라고 하며 이를 확인하는 방법은 다음과 같습니다.

먼저 Analyze를 이용하여 통계 데이터를 추출 합니다.

SQL>analyze table emp compute statistics


행이행과 행연쇄가 있는지 조사 합니다. 아래에서 chain_cnt 값은 행이행이나 행연쇄로 인해
여러 블록으로 쪼개져 있는 행의 수를 의미합니다.

SQL> SELECT table_name, num_rows, blocks, empty_blocks, avg_space, chain_cnt
        FROM    dba_table
        WHERE chain_cnt > 0; 

2013년 8월 13일 화요일

Time Base Recovery(1) 중요한 테이블이나 테이블의 데이터를 삭제 했을 때의 복구 방법 입니다. 관리자는 2005년 1월 10일 10시 30분경에 전날(1월9일) 오전 10시 무렵에 중요한 emp 테이블을 실수로 삭제 했다는 보고를 받았습니다. ----------------------------- 복구 과정 ----------------------------- 1. 현재 데이터베이스를 종료 SQL>conn / as sysdba SQL>shutdown immediate (또는 shutdown abort) 2. 현재 DB에 대해 cold backup을 실시 (cold backup에 관한 사항은 이전 강좌를 참고) (데이터파일과 리두 로그 파일, 컨트롤 파일도 같이 백업) 3. 마운트 단계까지 DB 시작 SQL>startup mount 4. 가장 최근에 백업된 데이터 파일로부터 복원 SQL>host copy c:\backup\*.dbf c:\oracle\oradata\wink\ (윈도우) SQL>!cp /backup/*.dbf /oracle/oradata/wink(유닉스 계열) 5. LOG_ARCHIVE_DEST로 지정된 아카이브 로그 폴더에 아카이브 로그 파일이 있는지 확인 (만약 Archive Log가 있는 디스크에 장애가 있어 접근이 어렵다면 아카이브 파일을 임의의 장소에 저장하고 alter system archive log start to ‘디렉토리이름’ 명령으로 변경 합니다) 6. recover 명령으로 1월9일 오전 10시 이전으로 복구(여기서는 9시 55분 상태로 복구) SQL>recover database until ‘2005-01-09 09:55:00’ 7. resetlogs 옵션을 이용하여 DB를 Open SQL>alter database open resetlogs; 8. 삭제된 emp 테이블이 있는지 확인 9. 복구 완료를 확인 하였으면 DB를 종료 후 cold backup을 한 후 Archive Log를 삭제 이상과 같은 방법으로 Time-Base Recovery를 진행하면 되지만 개인적인 생각 입니다만 Export Utility를 이용하여 매일매일 DB를 백업 받아 두었다면 Import를 이용하여 간단하게 복구를 진행 할 수 있을 것 같습니다. (물론 대량의 데이터를 매일매일 Export 한다는 것이 부담스러울 수도 있지만 말입니다. 제가 과거에 백화점에 근무 할 때도 매일매일 export로 전체 DB를 백업 받았던 기억이 납니다… ) [출처] 오라클자바커뮤니티 - http://www.oraclejavanew.kr/bbs/board.php?bo_table=LecBACKUP&wr_id=2

Time Base Recovery

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터

(신입사원채용무료교육, 오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷)  

중요한 테이블이나 테이블의 데이터를 삭제 했을 때의 복구 방법 입니다.

관리자는 2005년 1월 10일 10시 30분경에 전날(1월9일) 오전 10시 무렵에 중요한 emp 테이블을 실수로 삭제 했다는 보고를 받았습니다.


-----------------------------
복구 과정
-----------------------------

1.        현재 데이터베이스를 종료

SQL>conn / as sysdba
SQL>shutdown immediate (또는 shutdown abort)

2.        현재 DB에 대해 cold backup을 실시 (cold backup에 관한 사항은 이전 강좌를 참고)
(데이터파일과 리두 로그 파일, 컨트롤 파일도 같이 백업)

3.        마운트 단계까지 DB 시작

SQL>startup mount

4.        가장 최근에 백업된 데이터 파일로부터 복원

SQL>host copy c:\backup\*.dbf c:\oracle\oradata\wink\ (윈도우)

SQL>!cp /backup/*.dbf /oracle/oradata/wink(유닉스 계열)

5.        LOG_ARCHIVE_DEST로 지정된 아카이브 로그 폴더에 아카이브 로그 파일이 있는지 확인 (만약 Archive Log가 있는 디스크에 장애가 있어 접근이 어렵다면 아카이브 파일을 임의의 장소에 저장하고 alter system archive log start to ‘디렉토리이름’ 명령으로 변경 합니다)


6.        recover 명령으로 1월9일 오전 10시 이전으로 복구(여기서는 9시 55분 상태로 복구)

SQL>recover database until ‘2005-01-09 09:55:00’

7.        resetlogs 옵션을 이용하여 DB를 Open

SQL>alter database open resetlogs;

8.        삭제된 emp 테이블이 있는지 확인

9.        복구 완료를 확인 하였으면 DB를 종료 후 cold backup을 한 후 Archive Log를 삭제


이상과 같은 방법으로 Time-Base Recovery를 진행하면 되지만 개인적인 생각 입니다만 Export Utility를 이용하여 매일매일 DB를 백업 받아 두었다면 Import를 이용하여 간단하게 복구를 진행 할 수 있을 것 같습니다. (물론 대량의 데이터를 매일매일 Export 한다는 것이 부담스러울 수도 있지만 말입니다. 제가 과거에 백화점에 근무 할 때도 매일매일 export로 전체 DB를 백업 받았던 기억이 납니다… )


[ORACLEJAVA커뮤니티강좌, 백업/복구]오라클 불완전 복구 과정과 주의사항

불완전 복구 과정과 주의사항.


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터 
(신입사원채용무료교육, 오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷)  


------------------
복구과정
------------------

1. 오류를 확인하고 데이터베이스를 종료
2. close 백업(cold 백업)을 실시
3. 모든 데이터 파일을 복원(때에 따라서는 컨트롤 파일을 복구해야 하는 경우도 있슴)
4. startup mount 단계로 시작하여 recover 명령으로 복구
5. resetlog 옵션을 이용하여 데이터베이스를 오픈 한 다음 정상적인 동작을 확인
6. 데이터베이스를 종료하고 cold backup을 실시


--------------------
주의 사항
--------------------

-        불완전 복구(incomplete recovery)는 완전 복구(Complete Recovery)와는 달리 백업된 전체 데이터를 복원하고 recovery 하므로 반드시 복구 전에 데이터베이스를 종료 해야 합니다.
-        복구 실패에 대비해 recovery 전에 cold backup을 실시 합니다.
-        cold backup시 redo log file과 control file도 포함하여 백업을 하며 아카이브 로그도 별도의 공간에 백업을 해 둡니다.
-        불완전 복구는 mount 상태에서 복구가 진행되므로 일반 사용자는 DB를 사용할 수 없습니다.
-        백업된 모든 데이터 파일과 백업 시점에서 복구를 원하는 시점까지의 아카이브 로그가 필요 합니다.
-        복구가 끝난 후 resetlog 옵션을 통해 데이터베이스를 시작하면 로그 시퀀스가 초기화 되어 이전의 로그 파일이나 Archive Log File은 더 이상 이용할 수 없습니다. 그러므로 반드시 정상적으로 동작하는 것을 확인 후 cold backup을 해야 합니다. cold backup이 끝나면 이전에 만들어진 Archive Log File은 삭제 합니다.

오라클 export와 tablespace

oracle, oracle교육, oracle강좌, oraclejava, javaoracle, 오라클, 오라클자바, 자바오라클, 오라클교육, 오라클강좌, 구로디지털 오라클, 구로 오라클, 가산 오라클

export와 tablespace


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터 
(신입사원채용무료교육, 오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷)  

oracle9i에서는 지정된 tablespace의 object를 export 받기위한 옵션으로 tablespace parameter를 사용할 수 있게 되었습니다. (8i에서 이 parameter는 다른 데이터베이스로 옮길 테이블스페이스를 지정하였으나 9i에서는 지정된 테이블스페이스의 object를 export 하겠다는 개념으로 바뀜)

이 parameter를 사용하기 위해서는 해당 user에게 export_full_database privilege가 부여되어 있어야 하는데 아래의 예제를 보면서 이해 바랍니다.

----------------------------------------------------------------


C:\Documents and Settings\이종철>sqlplus /nolog

SQL*Plus: Release 9.2.0.1.0 - Production on Fri Mar 11 08:48:31 2005

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

SQL> conn / as sysdba
Connected.
SQL> create tablesapce test datafile
  2  'c:\oracle\oradata\wink\test01.dbf' size 1m;
create tablesapce test datafile
      *
ERROR at line 1:
ORA-00901: invalid CREATE command


SQL> create tablespace  test datafile
  2  'c:\oracle\oradata\wink\test01.dbf' size 1m;

Tablespace created.

SQL> conn scott/tiger
Connected.

SQL> create table mytest (
  2  id number,
  3  name varchar2(20),
  4  addr varchar2(50),
  5  amount number,
  6  hiredate date)
  7  partition by list(addr)
  8  (
  9  partition test_1 values ('서울','부산'),
 10  partition test_2 values ('광주','대구'),
 11  partition test_3 values ('제주','춘천') tablespace test,
 12  partition test_4 values ('수원','대전') tablespace users
 13  )
 14  /

Table created.

SQL> insert into mytest values (1,'1길동','서울',10000, sysdate);

1 row created.

SQL> insert into mytest values (2,'2길동','부산',20000, sysdate);

1 row created.

SQL> insert into mytest values (3,'3길동','제주',30000, sysdate);

1 row created.

SQL> insert into mytest values (4,'4길동','춘천',40000, sysdate);

1 row created.

SQL> insert into mytest values (5,'5길동','대전',50000, sysdate);

1 row created.

SQL> select segment_name, partition_name
  2  from user_segments
  3  where tablespace_name = 'TEST';

SEGMENT_NAME
--------------------------------------------------------------------------------

PARTITION_NAME
------------------------------
MYTEST
TEST_3


SQL> conn / as sysdba
Connected.
SQL> grant exp_full_database to scott;

Grant succeeded.

SQL> grant imp_full_database to scott;

Grant succeeded.

SQL> exit

Disconnected from Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production
EXP-00000: Export terminated unsuccessfully

C:\Documents and Settings\이종철>exp userid=scott/tiger tablespaces=test

Export: Release 9.2.0.1.0 - Production on Fri Mar 11 08:59:16 2005

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to: Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.1.0 - Production
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses KO16MSWIN949 character set (possible charset conversion)

About to export selected tablespaces ...
For tablespace TEST ...
. exporting cluster definitions
. exporting table definitions
. . exporting table                        MYTEST
. . exporting partition                        TEST_1          2 rows exported
. . exporting partition                        TEST_2          0 rows exported
. . exporting partition                        TEST_3          2 rows exported
. . exporting partition                        TEST_4          1 rows exported
. exporting referential integrity constraints
. exporting triggers
Export terminated successfully without warnings.


===================================================================
한가지 특이한 점은 지정된 tablespace 내의 object와 연관된 다른 tablespace의 object도 같이 export/import 된다는 것이다.
===================================================================

[ORACLEJAVA커뮤니티]DBMS_STATS 패키지 사용하기 오라클강좌

DBMS_STATS 패키지 사용하기 오라클강좌

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터 
(신입사원채용무료교육, 오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷)  
 
 
오라클은 테이블이나 인덱스와 같은 데이터베이스 오브젝트에 대한 통계 정보 생성을 용이하게 하기 위해 DBMS_STATS 패키지를 제공 합니다이 패키지를 이용하면 테이블이나 인덱스의 모든 데이터를 근간으로 통계 정보를 생성 할 수 있으며 생성된 Sample 데이터를 기반에서 하여 통계 정보를 평가 하는 것이 가능 합니다.
 
대용량의 테이블이라면 모든 데이터를 가지고 액세스 경로를 추측 하는 것 보다 이러한 샘플링 데이터를 가지고 추측하는 것이 훨씬 용이하다대체로 샘플링 데이터는 5% 이하로 row block에 만들며 DBMS_STATS PACKAGE automatic sampling procedure를 이용하는 것이 좋습니다.
 
통계정보용 테이블 생성하기 DBMS_STATS 패키지의 create_stat_table 프러시져를 이용하여 만들면 됩니다아래의 예를 보죠
 
SQL> conn / as sysdba
연결되었습니다.
SQL> execute dbms_stats.create_stat_table('scott','stat_tab','users');
 
PL/SQL 처리가 정상적으로 완료되었습니다.
 
여기에서 사용된 인자는 계정통계정보용 테이블 이름테이블스페이스 이름 입니다.
 
자 이번에는 통계정보를 모아 볼까요,,,
 
DBMS_STATS 패키지에는 몇 개의 유용한 프러시저가 있는데 다른 레벨로 통계 정보를 생성 할 수 있습니다.
 
Gather_database_ stats: 데이터베이스의 모든 Object에 대해 통계 정보를 생성 합니다.
Gather_schema_ stats: 해당 스키마의 Object에 대해 통계 정보를 생성 합니다.
Gather_table_stats : 테이블과 그 테이블과 연관된 인덱스에 대해 대해 통계 정보를 생성 합니다.
Gather_index_stats : 인덱스에 대해 대해 통계 정보를 생성 합니다.
 
아래의 예제를 참고 하세요
 
아래는 SCOTT이라는 스키마 계정과 EMP라는 테이블에 대해 통계 정보를 생성 했습니다.
 
SQL> execute dbms_stats.gather_schema_stats(ownname => 'scott');
 
PL/SQL 처리가 정상적으로 완료되었습니다.
 
SQL>  execute dbms_stats.gather_table_stats('scott','emp');
 
PL/SQL 처리가 정상적으로 완료되었습니다.
 
SQL>select * from dba_tables where owner = SCOTT 으로 확인 하자.
 
)위의 예제인 경우 자동으로 테이블과 인덱스의 모든 데이터에 대해 통계 정보가 계산 됩니다만약 만들 통계정보가 단순히 샘플이거나 큰 테이블의 모든 데이터가 아니라 일부의 레코드에 대해 제한하는 경우엔 dbms_stats.auto_sample_size를 이용 합니다아래의 예를 참고 하세요~
 
SQL> execute dbms_stats.gather_schema_stats(ownname => 'scott', estimate_percen => dbms_stats.auto_sample_size);
 
PL/SQL 처리가 정상적으로 완료되었습니다.
 
이번에 시스템과 관련된 통계 정보를 생성하여 보도록 하겠습니다.
 
dbms_stats를 이용하여 CBO(cost based optimizer)에게 system performance 통계정보를 제공 할 수 있는데  이 패키지는 CPU 사용과 I/O 퍼센트 등의 정보도 통계정보를 생성시 추가 합니다. dbms_stats.gather_system_stats 프러시저를 이용하면 되며 파라미터는 다음과 같습니다.
 
Gathering_mode : 통계 정보에 대한 수집을 특정한 시기 또는 기간에 하는 경우에는 interval 이나 start/stop 값을 주면 됩니다. noworkload라고 하면 시스템은 통계 정보를 general하게 수집 합니다.
 
Interval : Gathering_mode에서 interval이라고 한 경우에만 사용 합니다.
Stattab : 시스템의 통계 정보가 모아질 테이블을 기술 합니다.
 
Statown : 시스템의 통계 정보가 모아질 테이블의 Owner를 기술 합니다. (현재 패키지를 실행 할 Schema와 다를 경우에 기술 합니다)
 
SQL> begin
  2  dbms_stats.gather_system_stats (
  3     gathering_mode => 'interval',
  4     interval => 60,
  5     stattab => 'stat_tab',
  6     statown => 'scott');
  7  end;
8  /
 
PL/SQL 처리가 정상적으로 완료되었습니다.
 
)DBMS_STATS.gather_system_stats 를 사용전에 job_queue_processes 매개변수를 SET 시켜야 합니다기본값은 0으로 양수값으로 세팅 해야 합니다그렇지 않으면 gather_system_stats 프러시져가 동작하지 않을 수 있습니다현재 세션에서 이 값을 다이나믹하게 설정 할려면 alter system set job_queue_processes = 20 이라고 하면 됩니다.

oracle cursor sgaring parameter

cursor sgaring parameter

CURSOT_SHARING 파라미터


 
구로디지털 오엔제이프로그래밍실무교육센터
www.onjprogramming.co.kr
 
 
 
비슷한 조건 문을 가지는 문장에 대해 SQL문을 공유하기 위해서는 이전 강좌 처럼 바인드 변수를 이용 할 수 있습니다. 이전강좌에서 상수 값을 다르게 주게 되는 경우 서로 다른 SQL로 인식을 하여 하드 파싱(처음 보는 SQL문으로 인식하여 일일이 파싱)을 한다고 하였습니다.

 Oracle 8.1.6
에서 소개된 Cursor_Sharing 변수는 각각의 문장들에 대해 bind 변수로 처리하지 않게 되더라도 내부적으로 바인드 변수로 처리하여 각각의 Cursor에 대해 공유가 가능 하도록 했습니다. 실제 이 기능은 Bind 변수를 쓰는 것 보다는 빠르지 않지만 Literal SQL문을 이용하는 것보다 20~30% 성능 향상이 있는 것으로 검증 되었습니다.
 
1. CURSOR_SHARING = EXACT
 
SQL문장이 모두 동일해야만 Soft Parsing이 가능 합니다.(재사용 한다는 이야깁니다.) Where절의 상수까지도 같아야 합니다.
 
다음예문을 참고 하세요~
SQL>conn / as sysdba
SQL> alter system flush shared_pool;
 
시스템이 변경되었습니다.
 
SQL> conn scott/tiger
연결되었습니다.
SQL> alter session set cursor_sharing = exact;
 
세션이 변경되었습니다.
 
SQL> select dname from dept where deptno = 10;
 
DNAME
--------------
ACCOUNTING
 
SQL> select dname from dept where deptno = 40;
 
DNAME
--------------
OPERATIONS
 
SQL> conn / as sysdba
연결되었습니다.
 
SQL> select substr(sql_text,1,40) "SQL", count(*),
  2     sum(executions) "총 실행 횟수"
  3  from v$sqlarea
  4  where sql_text like '%dept%'
  5  group by substr(sql_text,1,40)
  6  having count(*) > 0
  7  order by 2;
 
 
 SQL                                        COUNT(*)    총 실행 횟수
---------- --------------------------------------------------
select dname from dept where deptno = 10         1            1
select dname from dept where deptno = 40         1            1
 
파싱을 2번한 것을 알 수 있습니다
 
 
2. CURSOR_SHARING = SIMILAR
 
SQL문은 동일 해야 하며 조건에 정의된 바인드 변수의 값이 다르더라도 하나의 SQL문으로 간주하여 Soft Parsing 합니다. 이 값은 결국 다른 상수 값을 사용하더라도 하나의 SQL문으로 인식합니다, 3번의 경우(FORCE)와 같은 결과를 나타냅니다.
 
SQL> alter system flush shared_pool;
 
시스템이 변경되었습니다.
 
SQL> conn scott/tiger
연결되었습니다.
SQL> alter session set cursor_sharing = similar;
 
세션이 변경되었습니다.
 
SQL> select dname from dept where deptno = 10;
 
DNAME
--------------
ACCOUNTING
 
SQL> select dname from dept where deptno = 40;
 
DNAME
--------------
OPERATIONS
 
SQL> conn / as sysdba
연결되었습니다.
 
SQL> select substr(sql_text,1,40) "SQL", count(*),
  2     sum(executions) "총 실행 횟수"
  3  from v$sqlarea
  4  where sql_text like '%dept%'
  5  group by substr(sql_text,1,40)
  6  having count(*) > 0
  7  order by 2;
 
 SQL                               COUNT(*)          총 실행 횟수
---------- --------------------------------------------------
select dname from dept where deptno = :"         1            2
 
파싱이 한번만 일어남을 알수 있다
 
 
 
3. CURSOR_SHARING = FORCE
 
WHERE 조건절에 정의된 상수가 다르더라도 Soft Parsiing을 합니다.
 
SQL> alter system flush shared_pool;
 
시스템이 변경되었습니다.
 
SQL> conn scott/tiger
연결되었습니다.
 
SQL> alter session set cursor_sharing = force;
 
세션이 변경되었습니다.
 
SQL> select dname from dept where deptno = 10;
 
DNAME
--------------
ACCOUNTING
 
SQL> select dname from dept where deptno = 40;
 
DNAME
--------------
OPERATIONS
 
SQL> conn / as sysdba
연결되었습니다.
 
SQL> select substr(sql_text,1,40) "SQL", count(*),
  2     sum(executions) "총 실행 횟수"
  3  from v$sqlarea
  4  where sql_text like '%dept%'
  5  group by substr(sql_text,1,40)
  6  having count(*) > 0
  7  order by 2;
 
 SQL                               COUNT(*)          총 실행 횟수
---------- --------------------------------------------------
select dname from dept where deptno = :"         1            2
 

[ORACLEJAVA커뮤니티강좌]오라클 통계정보 해석하기 , SET AUTOTRACE 이용 하기

SET AUTOTRACE 이용 하기

SQL*Plus
에서 사용자는 자동으로 Optimizer에서 실행계획과 통계정보를 얻을 수 있습니다. 이런 경우  AUTOTRACE를 사용하며 DML문을 성공적으로 수행 시 만들어지며 DML문의 성능 튜닝을 위한 방법으로 자주 이용 됩니다.

SET AUTOTRACE
를 사용하기 위해선 실행 계획용 테이블(PLAN_TABLE)이 존재해야 하며 구문을 활성화 하기 위해 SET AUTOTRACE ON, 비활성화 하기위해 SET AUTOTRACE OFF하고 하면 됩니다. 참고로 SET AUTOTRACE에서 사용 할 수 있는 옵션은 다음과 같습니다.

SET AUTOTRACE OFF :
기본값으로 AUTOTRACE를 수행하지 않습니다.
SET AUTOTRACE ON EXPLAIN :
실행계획만을 출력
SET AUTOTRACE ON STATISTICS :
통계정보만을 출력
SET AUTOTRACE ON :
옵티마이저의 실행계획과 통계정보, 질의의 실행 결과를 함께 출력
SET AUTOTRACE TRACEONLY [EXPLAIN] : SET AUTOTRACE ON
과 유사하지만 옵티마이저의 실행계획과 통계정보를 출력, 만약 EXPAIN이라고 하면 실행계획만 출력 합니다.

SQL> conn / as sysdba
연결되었습니다.

SQL> @d:\app\A\product\11.2.0\dbhome_1\sqlplus\admin\plustrce.sql
SQL>
SQL> drop role plustrace;
drop role plustrace
          *
1
행에 오류:
ORA-01919:
'PLUSTRACE'()가 존재하지 않습니다


SQL> create role plustrace;
롤이 생성되었습니다.

SQL>
SQL> grant select on v_$sesstat to plustrace;
권한이 부여되었습니다.

SQL> grant select on v_$statname to plustrace;
권한이 부여되었습니다.

SQL> grant select on v_$session to plustrace;
권한이 부여되었습니다.

SQL> grant plustrace to dba with admin option;
권한이 부여되었습니다.

SQL>
SQL> set echo off

SQL> grant plustrace to scott;
권한이 부여되었습니다.

SQL> conn scott/tiger
연결되었습니다.

SQL> @d:\app\A\product\11.2.0\dbhome_1\RDBMS\ADMIN\utlxplan.sql
테이블이 생성되었습니다.

여기 까지 하면 SQL*Plus에서 TRACE 하기위한 plustrace 롤을 SCOTT 이 부여 받았고 , 실행계획을 저장 할 테이블인 PLAN_TABLE도 생성된다.


/*
아래 set autotrace on SQL문이 실행될 때 마다 실행 계획과 통계정보, 그리고 SQL의 실행 결과까지 보기 위해서 입니다.

만약 set autotrace trace라고만 하면 실행 계획과 통계정보만 보여 줍니다.기능을 해제하기 위해서는 OFF라고 하면 됩니다.
*/
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
SQL>set autotrace trace   --쿼리 결과는 안 나온다.

SQL> select * from emp;
 
14 개의 행이 선택되었습니다.


Execution Plan
----------------------------------------------------------
Plan hash value: 3956160932

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |    14 |   532 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS FULL| EMP  |    14 |   532 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          8  consistent gets
          0  physical reads
          0  redo size
       1467  bytes sent via SQL*Net to client
        415  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         14  rows processed


SQL> set autotrace off   --trace 기능 해제

SQL> select count(*) from emp;

  COUNT(*)
----------
        14


SQL> set autotrace on; 

SQL> select deptno, min(sal) from emp
  2  group by deptno
  3  having min(sal) > (select min(sal) from emp
  4                       where deptno = 30)

  5  order by deptno;

    DEPTNO   MIN(SAL)
---------- ----------
        10       1300


Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   FILTER
   2    1     SORT (GROUP BY)
   3    2       TABLE ACCESS (FULL) OF 'EMP'
   4    1     SORT (AGGREGATE)
   5    4       TABLE ACCESS (FULL) OF 'EMP'




Statistics
----------------------------------------------------------
        191  recursive calls  //
재귀호출의 횟수          
         5  db block gets //
현재의 블록이 요구된 횟수
(DML or SELECT FOR UPDATE등에 의한 current mode로 읽힌 블록 수)
         28  consistent gets //
한 블록에 대해 요구된 consistent read 횟수
(SELECT했을 때 읽기 일관성 모드로 읽힌 블록 수)
          7  physical reads //
디스크로부터 읽어들인 데이터 블록의 총 개수
          0  redo size 리두로그가 만들어진 크기(SIZE)
        448  bytes sent via SQL*Net to client //Client
에 보내진 바이트수
        503  bytes received via SQL*Net from client //client
로부터 받은 바이트 수
          2  SQL*Net roundtrips to/from client  //
클라이언트에 송/수신된 Net메시지 합계 수
          3  sorts (memory) //
메모리에서 일어난 소트의 수
         0  sorts (disk) //
디스트에서 일어나 소트의 수
       1  rows processed //
연산을 하는 동안 처리한 ROW의 수
    
재귀적 호출이란, 오라클은 내부 처리를 위한 테이블을 관리 하며 이 테이블을 변화 시킬 때 내부적인 SQL문장을 생성하는데 이를 재귀적인 호출이라고 합니다. 예를 들면 테이블의 존재나 권한의 체크 등을 위한 SQL

[오라클자바community강좌]EXISTS 와 DISTINCT 비교 설명 입니다. 참고하세요~

[오라클자바community강좌]EXISTS  DISTINCT 비교 설명 입니다. 참고하세요~

오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터

(신입사원채용무료교육, 오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷)  
 
SELECT 문장에서 DISTINCT를 사용하는 이유는 중복된 행을 제거 하기 위해서 입니다이를 위해 오라클은 SORT를 수행 하며 소트를 위한 시간메모리 또는 디스크 공간이 필요 할 수도 있습니다그러니깐 가급적이면 사용 안 하는 것이 좋습니다추출되는 데이터가 순서에 의해 출력되지 않아도 된다면 아래의 경우처럼 EXISTS를 사용하는 것이 훨씬 효율적 입니다예제를 통해 이해 하도록 하겠습니다실제 비용은 1/10 정도로 줄게 됩니다.
:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 
SQL> set autotrace on
SQL> select distinct c.name
  2  from s_customer c, s_ord o
  3  where c.id = o.customer_id;
 
NAME
--------------------------------------------------
Beisbol Si!
Big John's Sports Emporium
:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />DelhiSports
Futbol Sonora
Hamada Sport
Kam's Sporting Goods
Kuhn's Sports
Muench Sports
OJ Atheletics
Ojibway Retail
Sportique
 
NAME
--------------------------------------------------
Unisports
Womansport
 
13 개의 행이 선택되었습니다.
 
   00:00:00.03
 
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   SORT (UNIQUE)
   2    1     NESTED LOOPS
   3    2       TABLE ACCESS (FULL) OF 'S_ORD'
   4    2       TABLE ACCESS (BY INDEX ROWID) OF 'S_CUSTOMER'
   5    4         INDEX (UNIQUE SCAN) OF 'S_CUSTOMER_ID_PK' (UNIQUE)
 
이 경우엔 S_ORD 테이블을 전체 스캔 한 데이터와 S_CUSTOMER 테이블의 데이터를 UNIQUE 인덱스를 이용하여 가져온 후 ROWIDD로 찾은 데이터와 비교하여 같은 아이디의 데이터가 있으면 추출하고 아니면 반복하는 구조를 가집니다그런 다음 c.name으로 SORT를 하게 되는 거죠
 
 
Statistics
----------------------------------------------------------
         80  recursive calls
          0  db block gets
         57  consistent gets
          0  physical reads
          0  redo size
        651  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         13  rows processed
 
이번엔 EXISTS를 이용하는 예 입니다.
 
SQL> select c.name
  2  from s_customer c
  3  where exists (select 1 from s_ord o
  4                where o.customer_id = c.id);
 
NAME
--------------------------------------------------
Unisports
OJ Atheletics
Delhi Sports
Womansport
Kam's Sporting Goods
Sportique
Muench Sports
Beisbol Si!
Futbol Sonora
Kuhn's Sports
Hamada Sport
 
NAME
--------------------------------------------------
Big John's Sports Emporium
Ojibway Retail
 
13 개의 행이 선택되었습니다.
 
   00:00:00.03
 
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   FILTER
   2    1     TABLE ACCESS (FULL) OF 'S_CUSTOMER'
   3    1     TABLE ACCESS (FULL) OF 'S_ORD'
 
이 경우엔 S_CUSTOMER를 전체 스캔하고 S_ORD도 전체 스캔하여 필터링(ID가 같은 데이터가 있는지하므로 SORT를 이용하지는 않습니다그러므로 앞의 쿼리와 추출되는 데이터의 개수는 같지만 순서는 달리 나오는 겁니다.
 
 
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         49  consistent gets
          0  physical reads
          0  redo size
        651  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         13  rows processed
 
 
[실습]
select * from dba_free_spaces
select * from dba_rollback_segs
 
create table cust (
   cust_id varchar2(10),
   cust_name varchar2(50));
  
  
create table sale(
    cust_id varchar2(10),
    goods_id varchar2(10),
    sale_amt number);
   
insert into cust values ('1', '김길동');
insert into cust values ('2', '홍길동');
insert into cust values ('3', '나길동');
insert into sale values ('1', 'A001',1000);
insert into sale values ('1', 'B001',2000);
insert into sale values ('2', 'C001',4000);
insert into sale values ('2', 'D001',5000);
commit
SQL> select * from cust;
CUST_ID        CUST_NAME                                         
-------------- --------------------------------------------------
1              김길동                                           
2              홍길동                                           
3              나길동                                           
3 rows selected.
SQL> select * from sale;
CUST_ID        GOODS_ID         SALE_AMT        
-------------- ---------------- ----------------
1              A001                         1000
1              B001                         2000
2              C001                         4000
2              D001                         5000
4 rows selected.
 
-- 매출이 있는 고객데이터가 4건이다.
SQL> select c.cust_name 
  from cust c, sale s
 where c.cust_id = s.cust_id;
CUST_NAME                                         
--------------------------------------------------
김길동                                           
김길동                                           
홍길동                                           
홍길동                                           
4 rows selected.
 


-- 이름이 같으면 한건만 로딩
SQL> select distinct c.cust_name 
  from cust c, sale s
 where c.cust_id = s.cust_id;
CUST_NAME                                         
--------------------------------------------------
김길동                                           
홍길동                                           
2 rows selected.

-- exists로 구현
SQL> select c.cust_name
  from cust c
 where exists (select 1 from sale s
               where s.cust_id = c.cust_id);
CUST_NAME                                         
--------------------------------------------------
김길동                                           
홍길동                                           
2 rows selected.