상세 컨텐츠

본문 제목

global temporary table 조회 방법?

프로그래밍/DB

by 라제폰 2008. 12. 29. 18:28

본문

다른 내용도 좋지만, 오라클 forum에서 발견한 자료네요.

global temporary table에 대한 내용 입니다. 참고 하세요...

=====================================================

 

No. 11818
TEMPORARY TABLE IN ORACLE8I
===========================
Oracle8.1에서는 session내에서 임시로 사용할 data들을 영구적인 segment형태가
아닌 temporary structure에서 관리할 수 있다.
이러한 Temporary Table들은 그 생성문장에 의해서 definition이 dictionary에
저장되고, 각 session에서 해당 table을 사용할 때마다 definition을 이용하여
memory에 table 구조를 생성하게 된다.

CHARACTERISTICS
---------------
1. data는 session private하다. (특정 session에서 사용하는 temporary table
   data는 다른 session에서 access할 수 없다.)
2. CREATE GLOBAL TEMPORARY TABLE ...
   ON COMMIT [DELETE|PRESERVE] ROWS ; 문을 이용하여 생성한다.
3. data의 유지기간은 transaction단위 또는 session단위이다.
   'ON COMMIT DELETE ROWS'로 생성되었다면 transaction단위이며 이때 data는
   commit이 되는 시점에 자동으로 제거된다.
   'ON COMMIT PRESERVE ROWS'로 생성되었다면 session단위이며 이때 data는
   해당 session이 종료되면서 사라진다.
   default는 'ON COMMIT DELETE ROWS'이다.
4. table의 definition은 dictionary에 permanently 저장된다.
   *_tables의 TEMPORARY, DURATION column이 temporary table과 관련이 있다.
   TEMPORARY - 'Y' : temporary type table
               'N' : permanent type table
   DURATION  - 'SYS$SESSION'     : data의 유지기간이 session단위
               'SYS$TRANSACTION' : data의 유지기간이 transaction단위
               NULL              : 해당 table은 temporary type이 아님
5. session간에 data에 대한 contention이 발생되지 않기 때문에 DML문에 대한
   lock이 필요하지 않다.
6. 임시적으로만 관리되는 data이므로 DML문에 대해서 redo log를 발생시키지
   않는다.
7. index, view, trigger를 생성하여 사용할 수 있다. Temporary Table의
   column에 생성되는 index도 temporary type이다.
8. table의 definition은 export utility를 이용하여 export할 수 있다.
   그러나 그 row들은 export의 대상이 될 수 없다.

RESTRICTIONS
------------
1. partitioned, index-organized, clustered table로 생성할 수 없다.
2. foreign key constraint를 설정할 수 없다.
3. nested table이나 varray type의 column은 포함할 수 없다.
4. 다음과 같은 LOB_storage_clause들은 지정할 수 없다. : TABLESPACE,
   storage_clause, LOGGING 또는 NOLOGGING, MONITORING 또는 NOMONITORING,
   또는 LOB_index_clause.
5. parallel DML이나 parallel query는 지원되지 않는다. (parallel hint는
   무시될 것이며, table생성시 parallel clause를 지정하면 error를
   return한다.)
6. storage나 tablespace는 지정할 수 없다.
7. 분산 transaction은 지원되지 않는다.

SAMPLE
------
----------------------------------------------------------------------
-- temporary type table을 생성하되 duration은 transaction단위로 한다.
----------------------------------------------------------------------
SQL> create global temporary table temp_tab
  2  (col1 number, col2 char(10))
  3  on commit delete rows ;

-----------------------------------------------------------------------
-- 생성된 table에 대한 정보를 조회한다. *_tables의 TEMPORARY, DURATION
-- column이 temporary type table과 관련이 있다.
-----------------------------------------------------------------------
SQL> select temporary, duration
  2  from user_tables
  3  where table_name = 'TEMP_TAB' ;
T DURATION
- ---------------
Y SYS$TRANSACTION

-----------------------------------------------------------------------
-- temporary table에 row insert
-----------------------------------------------------------------------
SQL> insert into temp_tab values (1, 'wookpark') ;
SQL> select * from temp_tab ;
     COL1 COL2
--------- ----------
        1 wookpark

-----------------------------------------------------------------------
-- transction을 commit한다.
-----------------------------------------------------------------------
SQL> commit ;
Commit complete.

-----------------------------------------------------------------------
-- duration이 transaction단위이기 때문에 commit을 수행하면 모든 data가
-- 사라진다.
-----------------------------------------------------------------------
SQL> select * from temp_tab ;
no rows selected
    
Overview of Temporary Tables
Introduction
~~~~~~~~~~~~
This is an overview of TEMPORARY TABLES introduced in Oracle8i.  This 
new feature allows temporary tables to be created automatically in a 
users temporary tablespace.
 
Syntax
~~~~~~
  CREATE GLOBAL TEMPORARY TABLE tablename ( columns )
        [ ON COMMIT PRESERVE | DELETE ROWS ]
 
  The default option is to delete rows on commit.
 
What Happens
~~~~~~~~~~~~
  When you create a GLOBAL TEMPORARY table a dictionary definition of
  the table is created. As soon as the table gets populated (on the first
  INSERT or at creation time for CTAS operations) a temporary segment is
  created in the users default TEMPORARY tablespace location. This temporary
  segments contents are just like a normal table.
  Point --> Users Default Temporary tablespace 일반적인 temporary tablespace
            혹은 temp 에 해당 임시 Segment 가 생성 된다.
 
  Different sessions using the same GLOBAL TEMPORARY table get allocated
  different temporary segments. The temporary segments are cleaned up
  automatically at session end or transaction end depending on the specified
  duration (ON COMMIT PRESERVE ROWS or ON COMMIT DELETE ROWS).
 
  Apart from the data visibility temporary tables can be used like ordinary
  tables for most operations.
 
 
Characteristics
~~~~~~~~~~~~~~~
 
1. Data exists only for the duration of either the session or 
   transaction.
 
   This can be specified in the create table command.
   For example:
 
       SQL> Create global temporary table emp_temp(eno number) 
              on commit delete rows;
 
     - OR -
 
       SQL> Create global temporary table emp_temp(eno number) 
              on commit preserve rows;
 
 
   ON COMMIT DELETE ROWS indicates a transaction level duration and
   PRESERVE indicates a session level duration.  
  
2. Data is visible only at session or transaction level.  Multiple 
   users using the same temporary table can see the definition
   of the table and their own data segment and nothing else.
 
3. Indexes, triggers and views can be created on these tables.
 
4. If an Index is created on temporary tables then it MUST be created 
   when the table is empty - ie: When there are NO temporary segments for 
   incarnations of the table. Indexes are implemented as separate 
   temporary segments.
 
5. No redo is generated for operations on the temporary table itself BUT
   undo is generated. Redo *IS* generated for the undo so temporary tables
   do indirectly generate redo.
 
6. The keyword GLOBAL indicates the table definition can be viewed
   by anybody with sufficient privileges - ie:using the same rules
   that apply to normal user tables. Currently only GLOBAL TEMPORARY
   tables are supported.
 
7. TRUNCATE operations truncate only the current session's incarnation
   of the table.
 
8. You can only export or import the definition not the data.
  
   Global Temporary table 을 export 후 결과물인 XXX.dmp 화일을
   vi 혹은 notepad 로 오픈 해보면
   create global temporary table .....
   및
   grant ... 의 문장을 볼수 있다. 
 
 
9. Segments get created only on the first insert (or CTAS) operation.
 
 
Drawbacks
~~~~~~~~~
 
1. The table definition is not dropped automatically. 
 
2. Only GLOBAL tables are supported right now, not local ones.   
 
3. Can perform DDL only when no session is bound to it. 
 
4. There is no underlying support for STATISTICS on GLOBAL 
   TEMPORARY tables so CBO (Cost Based Optimizer) has no statistical
   information to help determine an execution plan.
   NB: "ANALYZE TABLE COMPUTE/ESTIMATE STATISTICS" returns success 
       even though no statistics are gathered in 8i.   9i and higher 
       provides support for STATISTICS.
  
 
Constraints
~~~~~~~~~~~
 
Constraints can be implemented on the table either at the session or 
transaction level depending on the scope of the temporary table and
are not for the entire table even though the constraint is defined 
for the entire table.
==> Constraints 는 생성 가능 하나, Session 혹은 Transaction Scope 내에 존재 !!
 
If there is a primary key or unique key constraint, it is applicable only at
either session or transaction leve  i.e. two users can enter the same values
into the table from different sessions even though you have a primary / unique
key in place for the entire table (if the scope is the session )
 
In the case of a transaction level temporary table, the same values 
can be entered from different transactions.

 

 

### global temporary table 인지 체크 하는 방법은

dba_extents 에서 해당 테이블이름을 segment_name 과 join 하여

해당 extent 가 존재 하지 않으면 global temporary table 로 추측 하는방법뿐인듯싶다.

 

# 샘플 테이블 생성
SCOTT@CRAFT.WORLD> create global temporary table temp_tab
                   ( col1 number, col2 char(10))
                  on commit delete rows
Table created.

# 샘플 테이블 조회
SCOTT@CRAFT.WORLD> select temporary , duration from user_tables
                   where table_name ='TEMP_TAB';
T DURATION
- ---------------
Y SYS$TRANSACTION

# 샘플 데이타 입력
SCOTT@CRAFT.WORLD>insert into temp_tab values ( 1, 'wookpark');
1 row created.

# 샘플 데이타 조회 [ 자기 세션 에서 - 보인다. ]
SCOTT@CRAFT.WORLD>select * from temp_tab ;

      COL1 COL2
---------- ----------
         1 wookpark

# 샘플 데이타 조회 [ 다른 세션 에서 - 안보인다. ]
SCOTT@CRAFT.WORLD>select * from temp_tab ;
no rows selected

SCOTT@CRAFT.WORLD>commit ;
Commit complete.

# 샘플 데이타 다시 입력
SCOTT@CRAFT.WORLD>insert into temp_tab values ( 2, 'TG') ;
1 row created.

# 다른 세션에서 alter table 을 통한 칼럼 추가 시도
SCOTT@CRAFT.WORLD>alter table temp_tab add ( col3 number ) ;
alter table temp_tab add ( col3 number )
*
ERROR at line 1:
ORA-14450: attempt to access a transactional temp table already in use

# 다른 세션에서 truncate table 후  alter table 을 통한 칼럼 추가 시도
SCOTT@CRAFT.WORLD>truncate table temp_tab ;

Table truncated.

SCOTT@CRAFT.WORLD>alter table temp_tab add ( col3 number ) ;
alter table temp_tab add ( col3 number )
*
ERROR at line 1:
ORA-14450: attempt to access a transactional temp table already in use

## 모두 Fail

# 샘플 데이타 입력 세션에서 다시 commit
SCOTT@CRAFT.WORLD>commit ;
Commit complete.

# 칼럼 추가 시도 - 성공
SCOTT@CRAFT.WORLD>alter table temp_tab add ( col3 number ) ;
Table altered.


# Global temporary table 은 세션별 ( create 시 option ) 테이블이라
  사용중이면 alter table 이 먹지 않는다.
  또한 다른 Session 에서 Truncate 해도 의미 없다.

 

## global temporary table 을 사용중인 세션 찾을 후 Kill 후

    alter table 을 진행 하면 될것으로 생각된다.

 

## 실제 Global Temporary table 을 사용중인 세션은 v$transaction 을 통해서 찾을수 있다.

 

## 세션 1

SCOTT@CRAFT.WORLD>insert into temp_tab values ( 2, 'TG',3 ) ;

1 row created.

## 세션 2

SCOTT@CRAFT.WORLD>insert into temp_tab values ( 2, 'TGG', 3 ) ;

1 row created.
이상태에서 아래의 Query 실행

SQL> select sid, serial#, username, taddr, used_ublk, used_urec
         from v$transaction t, v$session s
         where t.addr = s.taddr;

       SID    SERIAL# USERNAME                       TADDR     USED_UBLK  USED_UREC
---------- ---------- ------------------------------ -------- ---------- ----------
        13       5168 SCOTT                          471623AC          1          1
        18       8988 SCOTT                          47162728           1          1

 

해당 세션 에서 사용중인 sql 문장을 추출해야한다.

 

define sid_num=&sid
define serial_num=&serial

SELECT /*+ ordered use_hash(s t) */ sql_text, piece
FROM v$session s, v$sqltext_with_newlines t
WHERE s.sid = 13
AND s.serial# = &serial_num AND s.sql_address = t.address
AND s.sql_hash_value = t.hash_value AND s.sql_hash_value <> 0
UNION ALL SELECT /*+ ordered use_hash(s t) */ sql_text, piece
FROM v$session s, v$sqltext_with_newlines t
WHERE s.sid = 13 AND s.serial# = 5168
AND s.prev_sql_addr = t.address AND s.prev_hash_value = t.hash_value
AND s.sql_hash_value = 0 ORDER BY piece

undefine sid_num
undefine serial_num


관련글 더보기