18c分布式事务 oracle_浅谈ORACLE的分布式事务
平臺環境: suk: linux as4 oracle 9201 primary: windows xp oracle 10.2.0.3 首先在primary數據庫上建立測試數據。 SQL create table test as select * from dba_objects; Table created. SQL insert into test select * from test; 9873 rows created. SQ
平臺環境:
suk: linux as4 + oracle 9201
primary: windows xp + oracle 10.2.0.3
首先在primary數據庫上建立測試數據。
SQL> create table test as select * from dba_objects;
Table created.
SQL> insert into test select * from test;
9873 rows created.
SQL> /
19746 rows created.
SQL> /
39492 rows created.
SQL> /
78984 rows created.
SQL> /
157968 rows created.
SQL> /
315936 rows created.
SQL> commit;
Commit complete.
以下操作都是在suk數據庫上執行:
一、例子1:先看兩個表都在(同一個)遠端
suk@ORACLE9I> select owner,count(1) fromtest@primary,dual@primary group by owner;
已選擇8行。
已用時間: 00: 00: 00.87
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT (REMOTE) Optimizer=ALL_ROWS (Cost=1824 Card
=670910 Bytes=11405470)
1 0 HASH (GROUP BY) (Cost=1824 Card=670910 Bytes=11405470)
2 1 NESTED LOOPS (Cost=1758 Card=670910 Bytes=11405470)
3 2 FAST DUAL (Cost=2 Card=1)
4 2 TABLE ACCESS (FULL) OF 'TEST' (TABLE) (Cost=1756 Card= PRIMARY
670910 Bytes=11405470)
suk@ORACLE9I> select /*+ rule */ owner,count(1) fromtest@primary,dual@primary group
by owner;
已選擇8行。
已用時間: 00: 00: 00.89
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT (REMOTE) Optimizer=HINT: RULE
1 0 SORT (GROUP BY)
2 1 NESTED LOOPS
3 2 FAST DUAL
4 2 TABLE ACCESS (FULL) OF 'TEST' (TABLE) PRIMARY
以上兩個例子可以說明:不管是CBO還是RBO,如果SQL中涉及的表都是遠端的,那么該語句在遠端執行,在得到結果后返回調用端。
這一點我們可以從執行計劃的SELECT STATEMENT (REMOTE)看出。
疑問:如果例子里兩個表是來自兩個不同遠端數據庫,那么兩個表的表連接操作會發生在哪里?是提交該sql語句的本地數據庫【傾向于此】,還是兩個不同遠端數據庫中的一個?
注釋:SELECT STATEMENT (REMOTE)是上述一個執行計劃里所有操作的根操作,即是這個執行計劃發起的第一個操作,后續的操作都是由它而產生的,它是一個提綱挈領的源操作。而該源操作SELECT STATEMENT (REMOTE)里的REMOTE表示該源操作所在的執行計劃是來自遠端的數據庫的,不是本地數據庫上執行的執行計劃。而像源操作SELECT
STATEMENT里的沒有REMOTE表示該源操作所在的執行計劃就是來自本地數據庫的,不是遠端數據庫上執行的執行計劃。
二、例子2:兩個包含了本地表和遠端表的查詢
接著再看兩個包含了本地表和遠端表的查詢:
suk@ORACLE9I> select owner,count(1) fromtest@primary,dual group by owner;
已選擇8行。
已用時間: 00: 00: 03.92
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE
1 0 SORT (GROUP BY)
2 1 NESTED LOOPS
3 2 TABLE ACCESS (FULL) OF 'DUAL'
4 2 REMOTE* PRIMARY
4 SERIAL_FROM_REMOTE SELECT "OWNER" FROM "TEST" "TEST"
suk@ORACLE9I> select /*+ rule */ owner,count(1) fromtest@primary,dual group by owner;
已選擇8行。
已用時間: 00: 00: 03.45
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=HINT: RULE
1 0 SORT (GROUP BY)
2 1 NESTED LOOPS
3 2 TABLE ACCESS (FULL) OF 'DUAL'
4 2 REMOTE* PRIMARY
4 SERIAL_FROM_REMOTE SELECT "OWNER" FROM "TEST" "TEST"
從以上兩個執行結果可以看出:無論是CBO還是RBO,當查詢包含了本地表和遠端表時,oracle總是先把遠端表的數據通過網絡傳送到SQL的發起端,再跟本地表進行關聯得到最終結果。
從SELECT STATEMENT和SERIAL_FROM_REMOTE SELECT "OWNER" FROM "TEST" "TEST"可以看出SQL是取得遠端數據后在本地執行。
疑問:如果是兩個表執行union all操作,也是oracle總是先把遠端表的數據通過網絡傳送到SQL的發起端,再跟本地表進行union all操作得到最終結果嗎?
同時,要注意一個現象:如果SQL涉及的表都在遠端,SQL共耗費不到1秒的時間;而如果一個表在本地,一個表在遠端,返回相同的結果SQL耗費時間達到3秒多。
還要注意的是:在這種分布式事務中,看執行計劃的資源消耗統計部分是沒有意義的,因為本地(SQL的發起端)是不知道遠端數據庫的資源消耗情況。這句話是針對例子2:兩個包含了本地表和遠端表的查詢來說的,而例子1:先看兩個表都在(同一個)遠端里執行計劃的資源消耗統計部分是有意義的,因為該執行計劃就是來自遠端數據庫,故而自然知道遠端數據庫的資源消耗情況。
三、hint:driving_site對分布式查詢調優的適用情況
到這里,可能很多人都會想到:如果本地表很小,遠端表(準確來說是數據源)很大,且返回結果比較少的情況下,將遠端表(大表)傳送到本地將會引起很大的資源消耗。
很明顯,要解決這樣的問題,最好是把本地表數據傳送到遠端,然后讓SQL在遠端執行,得到結果后再返回到SQL發起端。
幸運的是,oracle提供一個hint來應對這種情況:driving_site
下面我們用這個hint來測試一下:
suk@ORACLE9I> select /*+ driving_site(test) */owner,count(1) fromtest@primary,dual group by
owner;
已選擇8行。
已用時間: 00: 00: 01.25
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT (REMOTE) Optimizer=ALL_ROWS (Cost=8404591 C
ard=5479992102 Bytes=93159865734)
1 0 HASH (GROUP BY) (Cost=8404591 Card=5479992102 Bytes=931598
65734)
2 1 MERGE JOIN (CARTESIAN) (Cost=7524913 Card=5479992102 Byt
es=93159865734)
3 2 TABLE ACCESS (FULL) OF 'TEST' (TABLE) (Cost=1756 Card= PRIMARY
670910 Bytes=11405470)
4 2 BUFFER (SORT) (Cost=8402834 Card=8168)
5 4 REMOTE* OF 'DUAL' (REMOTE) (Cost=11 Card=8168) !
5 SERIAL_FROM_REMOTE SELECT 0 FROM "SYS"."DUAL" "A1"
suk@ORACLE9I> select /*+ rule driving_site(test) */ owner,count(1) fromtest@primary,dual group
by o
wner;
已選擇8行。
已用時間: 00: 00: 00.71
執行計劃
----------------------------------------------------------
0 SELECT STATEMENT (REMOTE) Optimizer=HINT: RULE
1 0 SORT (GROUP BY)
2 1 NESTED LOOPS
3 2 REMOTE* OF 'DUAL' (REMOTE) !
4 2 TABLE ACCESS (FULL) OF 'TEST' (TABLE) PRIMARY
3 SERIAL_FROM_REMOTE SELECT 0 FROM "SYS"."DUAL" "A1"
注意SELECT STATEMENT (REMOTE)和SERIAL_FROM_REMOTE SELECT 0 FROM "SYS"."DUAL" "A1"與之前的測試例子的變化。
從上面兩個例子可以看出:用了driving_site后,oracle將在該hint指定的數據庫上執行SQL,然后在把結果返回給SQL的發起端。這個HINT對CBO和RBO都適用。
簡單總結一下:
1、不管是CBO還是RBO,如果SQL中涉及的表都是遠端的,那么該語句在遠端執行,在得到結果后返回調用端。
2、無論是CBO還是RBO,當查詢包含了本地表和遠端表時,oracle總是先把遠端表的數據通過網絡傳送到SQL的發起端,再跟本地表進行關聯得到最終結果。
3、可以通過driving_site這個hint來執行SQL在那端執行。這個hints在某些特定條件下的分布式查詢調優非常有用。
本條技術文章來源于互聯網,如果無意侵犯您的權益請點擊此處反饋版權投訴
本文系統來源:php中文網
總結
以上是生活随笔為你收集整理的18c分布式事务 oracle_浅谈ORACLE的分布式事务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android开机时间统计,androi
- 下一篇: 计算机考试演示文稿模板,2018职称计算