建立基於事務和基於會話的臨時表及臨時表建索引的實驗
Oracle的臨時表只存在於某個回話或者事務的生命週期裡,此時臨時表中的資料只對當前這個會話可見。
當會話退出或者使用者提交commit和回滾rollback事務的時候,臨時表的資料自動清空,但是臨時表的結構以及後設資料還儲存在使用者的資料字典中。
臨時表的定義對所有會話SESSION都是可見的,但是表中的資料只對當前的會話或者事務有效.臨時表經常被用於存放一個操作的中間資料(資料處理的中間環節)。
臨時表由於不產生redo,能夠提高資料操作的效能。
臨時表不會產生鎖和等待。
實驗如下:
1.ON COMMIT DELETE ROWS 基於事務的臨時表,臨時表中的資料是基於事務的,當事物提交或者回滾時,臨時表中的資料將被清空
12:35:26 SQL> create global temporary table temp1 on commit delete rows as select * from dba_extents;Table created
14:06:29 SQL> select count(*) from temp1;
COUNT(*)
----------
0
14:08:16 SQL> insert into temp1 select * from dba_extents;
9221 rows inserted
14:09:02 SQL> select count(*) from temp1;
COUNT(*)
----------
9221
14:09:20 SQL> commit;
Commit complete
14:09:24 SQL> select count(*) from temp1;
COUNT(*)
----------
0
14:09:27 SQL> select * from temp1;
OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
------------------------------ -------------------------------------------------------------------------------- ------------------------------ ------------------ ------------------------------ ---------- ---------- ---------- ---------- ---------- ------------
2.PRESERVE ROWS 基於會話的臨時表,臨時表中的資料基於會話,當會話結束時,臨時表中的資料被清空。
14:15:16 SQL> create global temporary table temp2 on commit preserve rows as select * from dba_extents;Table created
14:15:39 SQL> select count(*) from temp2;
COUNT(*)
----------
9221
14:16:19 SQL> insert into temp2 select * from dba_extents;
9222 rows inserted
14:16:58 SQL> select count(*) from temp2;
COUNT(*)
----------
18443
14:17:15 SQL> commit;
Commit complete
14:17:18 SQL> select count(*) from temp2;
COUNT(*)
----------
18443
14:17:19 SQL>
再開啟一個會話進行查詢:
SQL> select count(*) from temp2;
COUNT(*)
----------
0
SQL> select * from temp2;
OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME EXTENT_ID FILE_ID BLOCK_ID BYTES BLOCKS RELATIVE_FNO
------------------------------ -------------------------------------------------------------------------------- ------------------------------ ------------------ ------------------------------ ---------- ---------- ---------- ---------- ---------- ------------
SQL>
3.臨時表上建立索引
會話1:環境及錯誤提示14:30:11 SQL> create global temporary table temp3 on commit preserve rows as select * from dba_objects;
Table created
14:31:22 SQL> select count(*) from temp3;
COUNT(*)
----------
72009
14:32:25 SQL> create index idx_temp3 on temp3(object_id);
create index idx_temp3 on temp3(object_id)
ORA-14452: attempt to create, alter or drop an index on temporary table already in use
對以上錯誤的解釋:create index idx_temp3 on temp3(object_id);用於會話相關,也就在事務結束後truncate data in the temporary table,但如果在會話未結束時要修改temporary table就會出現錯誤:
ORA-14452: attempt to create, alter or drop an index on temporary table already in use
此時可以從其它會話中來建索引。
會話2:建索引
SQL> create index idx_temp3 on temp3(object_id);
Index created
SQL> select index_name,index_type,table_owner,table_name from user_indexes where table_name='TEMP3';
INDEX_NAME INDEX_TYPE TABLE_OWNER TABLE_NAME
------------------------------ --------------------------- ------------------------------ ------------------------------
IDX_TEMP3 NORMAL BYS TEMP3
回到會話1:查詢新建索引的相關資訊
14:36:21 SQL> select index_name,index_type,table_owner,table_name from user_indexes where table_name='TEMP3';
INDEX_NAME INDEX_TYPE TABLE_OWNER TABLE_NAME
------------------------------ --------------------------- ------------------------------ ------------------------------
IDX_TEMP3 NORMAL BYS TEMP3
14:44:02 SQL> select count(*) from temp3;
COUNT(*)
----------
72009
14:44:35 SQL> select * from temp3 where object_id=50;
OWNER OBJECT_NAME SUBOBJECT_NAME OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_TIME TIMESTAMP STATUS TEMPORARY GENERATED SECONDARY NAMESPACE EDITION_NAME
------------------------------ -------------------------------------------------------------------------------- ------------------------------ ---------- -------------- ------------------- ----------- ------------- ------------------- ------- --------- --------- --------- ---------- ------------------------------
14:44:58 SQL> select table_name,tablespace_name from user_tables where table_name='TEMP3';
TABLE_NAME TABLESPACE_NAME
------------------------------ ------------------------------
TEMP3
14:46:19 SQL> select index_name,tablespace_name from user_indexes where table_name='TEMP3';
INDEX_NAME TABLESPACE_NAME
------------------------------ ------------------------------
IDX_TEMP3
14:47:05 SQL> select segment_name,tablespace_name from user_segments where segment_name in('TEMP3','IDX_TEMP3');
SEGMENT_NAME TABLESPACE_NAME
-------------------------------------------------------------------------------- ------------------------------
會話3:在新建的會話上,測試查詢是否能用到索引。第一次查詢未用到索引,因為表內無資料。第二次查詢從執行計劃中可以看到使用了索引
SQL> set autotrace on explain;
SQL> select * from temp3 where object_id=111;
未選定行
執行計劃
----------------------------------------------------------
Plan hash value: 2448592476
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 207 | 2 (0)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| TEMP3 | 1 | 207 | 2 (0)| 00:00:01 |
---------------------------------------------------------------------------
SQL>
SQL> set autotrace off;
SQL> select index_name,index_type,table_owner,table_name from user_indexes where table_name='TEMP3';
INDEX_NAME INDEX_TYPE
------------------------------ ---------------------------
TABLE_OWNER TABLE_NAME
------------------------------ ------------------------------
IDX_TEMP3 NORMAL
BYS TEMP3
SQL> select count(*) from temp3;
COUNT(*)
----------
0
SQL> insert into temp3 select * from dba_objects;
已建立72010行。
SQL> commit;
提交完成。
SQL> set autotrace on explain;
SQL> select * from temp3 where object_id=111;
未選定行
執行計劃
----------------------------------------------------------
Plan hash value: 3995552559
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 207 | 1 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEMP3 | 1 | 207 | 1 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | IDX_TEMP3 | 1 | | 1 (0)| 00:00:01 |
相關文章
- 【基礎知識】基於事物的臨時表和基於會話的臨時表會話
- 會話與事務級臨時表和dual表會話
- (轉) oracle 臨時表(事務級、會話級)Oracle會話
- 會話級臨時表會話
- Oracle 基礎 ----臨時表和物件表Oracle物件
- mysql 建立臨時表MySql
- SQL建立臨時表SQL
- 【臨時表空間組】臨時表空間組的建立、維護及應用
- Sqlserver 關於臨時表和表變數的總結SQLServer變數
- ORACLE臨時表和SQLSERVER臨時表異同OracleSQLServer
- 【儲存管理】建立臨時表空間組、建立臨時表空間組及使用
- mysql關於臨時表的總結MySql
- 關於with 臨時表 as的一些用法
- 臨時表空間的建立、刪除,設定預設臨時表空間
- Oracle的臨時表Oracle
- 臨時表的操作
- 【實驗】重建臨時表空間解決臨時表空間過大問題
- MySQL 5.7 新特性 共享臨時表空間及臨時表改進MySql
- 關於Oracle臨時表的使用的小經歷Oracle
- 關於oracle with table as 建立臨時表的用法示例以及使用with as 的優點Oracle
- Oracle事務臨時表的一個隱藏問題Oracle
- Oracle臨時表使用注意事項Oracle
- oracle 臨時表的使用Oracle
- MySQL 中的臨時表MySql
- SQLServer臨時表的使用SQLServer
- oracle臨時表的用法Oracle
- MySQL臨時表MySql
- PostgreSQL:臨時表SQL
- oracle臨時表Oracle
- Oracle 臨時表Oracle
- 關於 oracle 臨時表 ORA-14452Oracle
- Oracle基礎 02 臨時表空間 tempOracle
- 記憶體表和臨時表的區別記憶體
- SQL Server中的臨時表和表變數SQLServer變數
- 再議臨時表和表變數變數
- mysql臨時表和記憶體表MySql記憶體
- 【臨時表空間】11g中使用 SHRINK方法縮小臨時表空間和臨時檔案
- mysql的內部臨時表MySql