Direct Path Insert與APPEND, PARALLEL的梳理與小結
裡面的寫入資料方式分為2種,一個是傳統方式寫入(conventional insert),另外一個是直接路徑寫入(direct path insert)。
傳統方式寫入: Oracle會重用表裡面空閒空間,並且寫入會先寫入到buffer cache。
直接路徑寫入:Oracle不重用表裡面的空閒空間,直接寫入到新分配的塊,並且資料直接寫入到data file,不寫入到buffer cache。效率更高。如果表的並行度不為1,那麼直接路徑寫入是預設的寫入行為(需要開啟會話並行dml)。直接路徑寫入為後設資料(例如空間擴充套件引起的資料字典資料變化)變更產生REDO, UNDO。而資料變更,redo,undo生成情況如下:
@ 不為資料寫入生成undo
@ 如果為非歸檔或者沒有開啟force logging,那麼直接路徑寫入時,不為資料寫入產生redo,這時與表是否設定nologging屬性無關。
@ 如果資料庫為歸檔,但是沒有開啟force logging,logging的表會產生redo,nologging的表不會產生redo。
@ 如果資料庫為歸檔並且開啟了force logging,資料寫入會產生redo,無論是否設定logging,nologging。
直接路徑寫入的一些限制:
@ 在一個事務裡面,可以執行多次直接路徑寫入,一旦該事物並行修改了表,分割槽或者索引,當前會話將無法再次方位該物件。例如會話A在表T上進行直接路徑寫入後,會話A無法再次訪問表T,但是會話B可以查詢表T,此時如果會話A執行一個傳統路徑寫入,會被阻塞,等待事件為:enq: TM – contention。
@ 目標表不能是cluster,不能含有object型別欄位,不能含有外來鍵約束,觸發器。
@ 對於目標表是IOT表,也有一些限制。
@ 分散式寫入無法進行直接路徑寫入。
APPEND,PARALLE和直接路徑寫入關係:
Append預設也是採用直接路徑寫入,不要求session enable parallel。
Parallel 要求會話級別enable parallel,否則將無法進行直接路徑寫入。
如下:
點選(此處)摺疊或開啟
-
SQL> select log_mode, force_logging from v$database;
-
-
LOG_MODE FORCE_
-
------------------------ ------
-
ARCHIVELOG NO
-
-
SQL> select * from v$version;
-
-
BANNER
-
-------------------------------------------------------------------------------------------------------------------
-
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
-
PL/SQL Release 11.2.0.3.0 - Production
-
CORE 11.2.0.3.0 Production
-
TNS for Linux: Version 11.2.0.3.0 - Production
-
NLSRTL Version 11.2.0.3.0 - Production
-
-
===scott測試使用者,構造測試資料來源和資料表
-
SQL> conn scott/tiger;
-
Connected.
-
SQL> create table t_data_pool as select * from dba_objects;
-
-
Table created.
-
-
SQL> create table t_direct_test as select * from t_data_pool where 1=2;
-
-
Table created.
-
- SQL>
點選(此處)摺疊或開啟
-
==場景1,Redo的量
-
SQL> set autot on;
-
SQL> insert into t_direct_test select * from t_data_pool;
-
-
75696 rows created.
-
-
-
Execution Plan
-
----------------------------------------------------------
-
Plan hash value: 2724272089
-
-
------------------------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-
------------------------------------------------------------------------------------------
-
| 0 | INSERT STATEMENT | | 76299 | 15M| 216 (1)| 00:00:03 |
-
| 1 | LOAD TABLE CONVENTIONAL | T_DIRECT_TEST | | | | |
-
| 2 | TABLE ACCESS FULL | T_DATA_POOL | 76299 | 15M| 216 (1)| 00:00:03 |
-
------------------------------------------------------------------------------------------
-
-
Note
-
-----
-
- dynamic sampling used for this statement (level=2)
-
-
-
Statistics
-
----------------------------------------------------------
-
266 recursive calls
-
10388 db block gets
-
3228 consistent gets
-
784 physical reads
-
8845208 redo size ==> redo 量
-
837 bytes sent via SQL*Net to client
-
807 bytes received via SQL*Net from client
-
3 SQL*Net roundtrips to/from client
-
2 sorts (memory)
-
0 sorts (disk)
-
75696 rows processed
-
-
SQL> commit;
-
-
Commit complete.
-
-
==使用append, logging時,redo量測試如下:
-
SQL> insert /*+append*/ into t_direct_test select * from t_data_pool;
-
-
75696 rows created.
-
-
-
Execution Plan
-
----------------------------------------------------------
-
ERROR:
-
ORA-12838: cannot read/modify an object after modifying it in parallel
-
-
-
SP2-0612: Error generating AUTOTRACE EXPLAIN report
-
-
Statistics
-
----------------------------------------------------------
-
94 recursive calls
-
1397 db block gets
-
1204 consistent gets
-
0 physical reads
-
8890936 redo size ==>redo 量
-
823 bytes sent via SQL*Net to client
-
819 bytes received via SQL*Net from client
-
3 SQL*Net roundtrips to/from client
-
1 sorts (memory)
-
0 sorts (disk)
-
75696 rows processed
-
-
SQL> commit;
-
-
Commit complete
-
-
-
==nologging append量,明顯很少了
-
SQL> alter table t_direct_test nologging;
-
-
Table altered.
-
-
SQL> insert /*+append*/ into t_direct_test select * from t_data_pool;
-
-
75696 rows created.
-
-
-
Execution Plan
-
----------------------------------------------------------
-
ERROR:
-
ORA-12838: cannot read/modify an object after modifying it in parallel
-
-
-
SP2-0612: Error generating AUTOTRACE EXPLAIN report
-
-
Statistics
-
----------------------------------------------------------
-
139 recursive calls
-
1361 db block gets
-
1229 consistent gets
-
0 physical reads
-
20904 redo size ==>Redo 量
-
824 bytes sent via SQL*Net to client
-
819 bytes received via SQL*Net from client
-
3 SQL*Net roundtrips to/from client
-
7 sorts (memory)
-
0 sorts (disk)
-
75696 rows processed
-
-
SQL> select count(1) from t_direct_test;
-
select count(1) from t_direct_test
-
*
-
ERROR at line 1:
-
ORA-12838: cannot read/modify an object after modifying it in parallel
- ==此時不提交,當前事務是無法訪問到該物件的,其他session可以。
新開會話B,
點選(此處)摺疊或開啟
-
oracle@ora11gr2 ~]$sqlplus scott/tiger
-
SQL*Plus: Release 11.2.0.3.0 Production on Wed Jun 11 12:30:31 2014
-
-
Copyright (c) 1982, 2011, Oracle. All rights reserved.
-
-
-
Connected to:
-
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
-
With the Partitioning, OLAP, Data Mining and Real Application Testing options
-
-
SQL> select count(1) from t_direct_test;
-
-
COUNT(1)
-
----------
-
151392
-
- SQL> insert into t_direct_test select * from t_data_pool; ==會被阻塞
點選(此處)摺疊或開啟
-
當前會話申請0號TM鎖被直接路徑寫入會話阻塞,直接路徑寫入會話持有Exclusive(6) TM鎖。
-
col resource format a20
-
col sid format 9999
-
col request for a15
-
Select Type || '-' || Id1 || '-' || Id2 "resource",
-
Sid,
-
Decode(Lmode,
-
0,
-
'None',
-
1,
-
'Null',
-
2,
-
'Row share',
-
3,
-
'Row Exclusive',
-
4,
-
'Share',
-
5,
-
'Share Row Exclusive',
-
6,
-
'Exlusive') Lock_Type,
-
Decode(Request,
-
0,
-
'None',
-
1,
-
'Null',
-
2,
-
'Row share',
-
3,
-
'Row Exclusive',
-
4,
-
'Share',
-
5,
-
'Share Row Exclusive',
-
6,
-
'Exlusive') Request,
-
Ctime,
-
Block
-
From V$lock
-
Where Type In ('TX', 'TM')
-
37 Order By "resource", Ctime Desc;
-
-
resource SID LOCK_TYPE REQUEST CTIME BLOCK
-
-------------------- ----- -------------------------------------- --------------- ---------- ----------
-
TM-5124-0 44 Row Exclusive None 905 0
-
TM-78585-0 29 Row Exclusive None 2912 0
-
TM-78587-0 44 Exlusive None 906 1 ====> TM上持有6號鎖
-
TM-78587-0 58 None Row Exclusive 380 0 ====> TM上被阻塞
-
TX-262166-8704 44 Exlusive None 906 0
-
TX-458782-8781 29 Exlusive None 2912 0
-
-
6 rows selected.
-
- SQL>
點選(此處)摺疊或開啟
- Sid為44的正在執行直接路徑插入,當時還沒有提交,而58號 會話在執行一個傳統路徑寫入
2、測試append,parallel的預設插入方式
上面的測試已經表名,在表預設的並行度為1的情況下,直接append是會選擇直接路徑寫入方式。下面現將表t_direct_test的並行度設定為4.
點選(此處)摺疊或開啟
-
SQL> conn scott/tiger
-
Connected.
-
SQL> col owner for a10
-
SQL> col degree for 999
-
SQL> col table_name for a20
-
SQL> select owner, table_name, Degree from dba_tables Where table_name = Upper('t_direct_test');
-
-
OWNER TABLE_NAME DEGREE
-
---------- -------------------- --------------------------------------------------------------------------------
-
SCOTT T_DIRECT_TEST 1
-
-
SQL> alter table t_direct_test parallel 4;
-
-
Table altered.
-
-
SQL> select owner, table_name, Degree from dba_tables Where table_name = Upper('t_direct_test');
-
-
OWNER TABLE_NAME DEGREE
-
---------- -------------------- --------------------------------------------------------------------------------
-
SCOTT T_DIRECT_TEST 4
-
-
SQL> insert into t_direct_test select * from t_data_pool;
-
-
75696 rows created.
-
-
SQL> select count(1) from t_direct_test; ==>沒有報錯,即表明沒有用到直接路徑寫入
-
-
COUNT(1)
-
----------
-
378480
-
-
SQL> commit;
-
-
Commit complete.
-
-
SQL> alter session enable parallel dml;
-
-
Session altered.
-
-
SQL> insert into t_direct_test select * from t_data_pool;
-
-
75696 rows created.
-
-
SQL> select count(1) from t_direct_test;
-
==報錯,說明在會話開啟允許並行dml的情況下,會直接使用直接路徑寫入方式。
-
select count(1) from t_direct_test
-
*
-
ERROR at line 1:
-
ORA-12838: cannot read/modify an object after modifying it in parallel
-
- SQL>
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29209863/viewspace-2133642/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20180905]lob與direct path read.txt
- alter table nologging /*+APPEND PARALLEL(n)*/APPParallel
- direct path read/read temp等待事件事件
- Flutter Path(一) : Path 與 CustomPainterFlutterAI
- mooc-CSS方面的總結與梳理CSS
- 《Node.js》path.resolve與path.join的區別與作用Node.js
- insert()與substr()函式函式
- jquery中append()方法與after()方法的區別jQueryAPP
- Oracle direct path read相關隱含引數Oracle
- 【TUNE_ORACLE】等待事件之IO等待“direct path read”Oracle事件
- 【TUNE_ORACLE】等待事件之IO等待“direct path write”Oracle事件
- 【廖雪峰python入門筆記】list新增元素_append()和insert()Python筆記APP
- 【TUNE_ORACLE】等待事件之IO等待“direct path write temp”Oracle事件
- DETR與Deformable DETR小結ORM
- 對資料中臺的梳理與思考
- 【資料結構與演算法】揹包問題總結梳理資料結構演算法
- equals與hashCode關係梳理
- 小程式與Vue對比·class與style繫結Vue
- OpenMP Parallel Construct 實現原理與原始碼分析ParallelStruct原始碼
- cookie path路徑與domain域CookieAI
- 使用setInterval與clearInterval踩的小坑總結
- (一):小程式與伺服器的連結伺服器
- 演算法與資料結構系列 ( 四 ) - 插入排序法- Insert Sort演算法資料結構排序
- insert into select語句與select into from語句
- 微信小程式登入流程梳理總結微信小程式
- parallel rollback引數總結Parallel
- Python中的一些陷阱與技巧小結Python
- 異常測試實踐與梳理
- 深入理解 RxJava2:論 Parallel 與併發(5)RxJavaParallel
- electron打包更新與整合sqlite小總結SQLite
- Flutter UI 1.0.2落地與優化小結FlutterUI優化
- 淺析Vue原始碼(九)——VirtualDOM與pathVue原始碼
- 互斥鎖與條件變數學習與應用小結變數
- 演算法與資料結構系列 ( 五 ) - 插入排序法改進- Insert Sort演算法資料結構排序
- Oracle中的insert/insert all/insert firstOracle
- 子域名資訊蒐集思路與技巧梳理
- 資料治理之資料梳理與建模
- Exadata混合列壓縮功能與INSERT語句BF
- 等待事件wait for a undo record 與 fast_start_parallel_rollback引數事件AIASTParallel