通過測試用例瞭解Oracle Temp表空間具體使用情況
Oracle Temp表空間具體使用資訊分析
1查詢臨時表空間大小
SQL>select tablespace_name,file_name,autoextensible,bytes/1024/1024,maxbytes/1024/1024 from dba_temp_files;
TABLESPACE_NAME FILE_NAME AUT BYTES/1024/1024 MAXBYTES/1024/1024
-------------------- ------------------------------------------------------------ --- --------------- ------------------
TEMP +ASMVG1/orcl/tempfile/temp.262.1005600277 YES 20 32767.9844
2.測試環境
sqlplus / as sysdba
create user myoracle identified by oracle;
grant connect,resouce to myoracle;
create table test_objs as select * from dba_objects;
exit
sqlplus myorace/oracle
select a.* ,b.* from test_objs a,test_objs b order by 1,2;
新開一會話
sqlplus / as sysdba
SQL> select username,sql_id,tablespace,segtype,extents from v$tempseg_usage;
SQL> /
USERNAME SQL_ID TABLESPACE SEGTYPE EXTENTS
------------------------------ ------------- ------------------------------- --------- ----------
MYORACLE 0a003svjmcz8t TEMP SORT 50
SQL> /
USERNAME SQL_ID TABLESPACE SEGTYPE EXTENTS
------------------------------ ------------- ------------------------------- --------- ----------
MYORACLE 0a003svjmcz8t TEMP SORT 59
使用關聯查詢可以確定正在消耗TEMP空間的sql詳細資訊
SQL> SELECT a.username, a.sid, a.serial#, a.osuser,a.schemaname,a.program,a.type,b.tablespace,b.sql_id, to_char(trunc((b.blocks * d.value) / 1024 /1024)) || ' MB' size
2 , b.segtype , c.sql_text
3 FROM v$session a, v$tempseg_usage b, v$sqlarea c
4 , (select value from v$parameter where name = 'db_block_size') d
5 WHERE a.saddr = b.session_addr
6 AND c.address= a.sql_address
7 AND c.hash_value = a.sql_hash_value
8 ORDER BY b.tablespace, b.blocks;
no rows selected
SQL> /
USERNAME SID SERIAL# OSUSER SCHEMANAME PROGRAM TYPE TABLESPACE SQL_ID SIZ SEGTYPESQL_TEXT
------------------------------ ---------- ---------- ------------------------------ ------------------------------ ------------------------------------------------ ---------- ------------------------------- ------------- ------------------------------------------- --------- ------------------------------------------------------------
MYORACLE 60 11 oracle MYORACLE sqlplus@rac1 (TNS V1-V3) USER TEMP dyk4dprp70d74 216 MB SORT select a.* ,b.* from test_objs a,test_objs b order by 1,2
SQL> /
USERNAME SID SERIAL# OSUSER SCHEMANAME PROGRAM TYPE TABLESPACE SQL_ID SIZ SEGTYPESQL_TEXT
------------------------------ ---------- ---------- ------------------------------ ------------------------------ ------------------------------------------------ ---------- ------------------------------- ------------- ------------------------------------------- --------- ------------------------------------------------------------
MYORACLE 60 11 oracle MYORACLE sqlplus@rac1 (TNS V1-V3) USER TEMP dpgnh97fq0yhu 226 MB SORT select a.* ,b.* from test_objs a,test_objs b order by 1,2
此時從檢視v$tempseg_usage;可以清楚看出臨時段的使用情況。如果該買遊戲賬號平臺地圖SQL使用了大量的temp空間必然執行很慢,可以檢視其執行計劃分析SQL語句和執行計劃作出優化處理。
select * from table(dbms_xplan.display_cursor('dyk4dprp70d74'));
select * from table(dbms_xplan.display_cursor('dpgnh97fq0yhu'));
SQL> select * from table(dbms_xplan.display_cursor('dpgnh97fq0yhu'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_IDdpgnh97fq0yhu, child number 0
-------------------------------------
select a.* ,b.* from test_objs a,test_objs b order by 1,2
Plan hash value: 3670659157
-------------------------------------------------------------------------------------------
| Id| Operation | Name | Rows| Bytes |TempSpc| Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
|0 | SELECT STATEMENT | | | | | 29M(100)| |
|1 |SORT ORDER BY | |241M | 93G|102G | 29M(1) |98:51:41 |
|2 |MERGE JOIN CARTESIAN| |241M | 93G | |838K(2) | 02:47:39 |
|3 | TABLE ACCESS FULL | TEST_OBJS | 15549 |3143K| | 56(2) | 00:00:01 |
|4 | BUFFER SORT | | 15549 |3143K| | 29M(1)| 98:51:40 |
|5 | TABLE ACCESS FULL | TEST_OBJS | 15549 |3143K| | 54(2) | 00:00:01 |
-------------------------------------------------------------------------------------------
Note
-----
- dynamic sampling used for this statement (level=2)
21 rows selected.
分析執行計劃,全表掃描,笛卡爾積,笛卡爾結果集再一次做排序,都及其耗費CPU資源和I/O資源
可以進一步從ASH分析
SQL>select sql_id,SQL_PLAN_LINE_ID,SQL_PLAN_OPERATION,event,count(*) from v$active_session_history where sql_id='dpgnh97fq0yhu' group by sql_id,SQL_PLAN_LINE_ID,SQL_PLAN_OPERATION,event
SQL_ID SQL_PLAN_LINE_ID SQL_PLAN_OPERATION EVENT COUNT(*)
------------- ---------------- ------------------------------ ---------------------------------------- ----------
dpgnh97fq0yhu 4 BUFFER 2
dpgnh97fq0yhu 0 SELECT STATEMENT Disk file operations I/O 1
dpgnh97fq0yhu 0 SELECT STATEMENT control file sequential read 3
dpgnh97fq0yhu 0 SELECT STATEMENT DFS lock handle 19
dpgnh97fq0yhu 0 SELECT STATEMENT enq: CF - contention 3
dpgnh97fq0yhu 1 SORT 16
dpgnh97fq0yhu 0 SELECT STATEMENT 3
7 rows selected.
如果當前沒有SQL在使用Temp空間,則如下兩個檢視沒有資料呈現
SQL> select * from v$tempseg_usage;
no rows selected
SQL> select * from v$sort_usage;
no rows selected
一旦TEMP空間被使用,則如下兩個查詢確定TEMP空間被使用了多少
SQL> select tablespace_name,file_name,autoextensible,bytes/1024/1024,maxbytes/1024/1024 from dba_temp_files
TABLESPACE_NAME FILE_NAME AUT BYTES/1024/1024 MAXBYTES/1024/1024
------------------------------ -------------------------------------------------- --- --------------- ------------------
TEMP +ASMVG1/orcl/tempfile/temp.262.1005600277 YES 407 32767.9844
SQL> select TABLESPACE_NAME,TOTAL_BLOCKS,USED_BLOCKS,FREE_BLOCKS from v$sort_segment;
TABLESPACE_NAME TOTAL_BLOCKS USED_BLOCKS FREE_BLOCKS
------------------------------- ------------ ----------- -----------
TEMP 51456 0 51456
SQL> select 51456*8/1024 from dual;
51456*8/1024
------------
402
如果SQL正在使用TEMP空間,則查詢v$sort_segment會顯示USED_BLOCKS,此時FREE_BLOCKS
SQL>select TABLESPACE_NAME,TOTAL_BLOCKS,USED_BLOCKS,FREE_BLOCKS from v$sort_segment;
TABLESPACE_NAME TOTAL_BLOCKS USED_BLOCKS FREE_BLOCKS
------------------------------- ------------ ----------- -----------
TEMP 56960 56960
一旦佔用TEMP表空間的SQL結束,則檢視v$sort_segment資訊顯示如下所示
SQL> select TABLESPACE_NAME,TOTAL_BLOCKS,USED_BLOCKS,FREE_BLOCKS from v$sort_segment;
TABLESPACE_NAME TOTAL_BLOCKS USED_BLOCKS FREE_BLOCKS
------------------------------- ------------ ----------- -----------
TEMP 0 62336
此時TOTAL_BLOCKS和FREE_BLOCKS相同,說明此時的TEMP表空間可以繼續給其他SQL使用。
通過v$temp_space_header查詢臨時表空間已經使用過的最大空間,這個檢視是永久化的。
SQL> select TABLESPACE_NAME,sum(BYTES_USED)/1024/1024,sum(BYTES_FREE)/1024/1024from v$temp_space_header group byTABLESPACE_NAME;
TABLESPACE_NAME SUM(BYTES_USED)/1024/1024 SUM(BYTES_FREE)/1024/1024
------------------------------ ------------------------- -------------------------
TEMP 492
可以看到執行計劃的步驟1耗時最多,這也是該SQL慢的核心原因
一旦SQL語句結束,則該檢視不再有資料呈現。