1. 程式人生 > >深入理解Oracle 的並行執行

深入理解Oracle 的並行執行

Oracle並行執行是一種分而治之的方法。執行一個sql 時,分配多個並行程序同時執行資料掃描,連線以及聚合等操作,使用更多的資源,得到更快的sql 響應時間。並行執行是充分利用硬體資源,處理大量資料時的核心技術。 

在本文中,在一個簡單的星型模型上,我會使用大量例子和sql monitor 報告,力求以最直觀簡單的方式,向讀者闡述並行執行的核心內容:

• Oracle 並行執行為什麼使用生產者——消費者模型。 
• 如何閱讀並行執行計劃。 
• 不同的資料分發方式分別適合什麼樣的場景。 
• 使用partition wise join 和並行執行的組合提高效能。 
• 資料傾斜會對不同的分發方式帶來什麼影響。 
• 由於生產者-­‐消費者模型的限制,執行計劃中可能出現阻塞點。 
• 布隆過濾是如何提高並行執行效能的。 
• 現實世界中,使用並行執行時最常見的問題。

術語說明:

  1. S: 時間單位秒。
  2. K: 數量單位一千。
  3. M:  數量單位一百萬,  或者時間單位分鐘。
  4. DoP: Degree of Parallelism, 並行執行的並行度。
  5. QC: 並行查詢的 Query Coordinator。
  6. PX 程序: Parallel Execution Slaves。
  7. AAS: Average active session, 並行執行時平均的活動會話數。
  8. 分發: pq distribution method, 並行執行的分發方式, 包括 replicate, broadcast, hash 和 adaptive分發等 4 種方式, 其中 adaptive 分發是 12c 引入的的新特性, 我將在本篇文章中一一闡述。
  9. Hash join 的左邊: 驅動表, the build side of hash join, 一般為小表。
  10. Hash join 的右邊: 被驅動表, the probe side of hash join, 一般為大表。
  11. 布隆過濾: bloom filter, 一種記憶體資料結構, 用於判斷一個元素是否屬於一個集合。

測試環境和資料

Oracle版本為12.1.0.2.2,兩個節點的RAC,硬體為ExadataX3-­‐8。

這是一個典型的星型模型,事實表lineorder有3億行記錄,維度表part/customer分別包含1.2M

和1.5M行記錄,3個表都沒有進行分割槽,lineorder大小接近30GB。 

 

select
owner seg_owner,
segment_name seg_segment_name, round(bytes/1048576,2) SEG_MB
from
 
dba_segments where
owner = 'SID'
and segment_name in ('LINEORDER','PART','CUSTOMER')
/

OWNER	SEGMENT_NAME SEGMENT_TYPE	SEG_MB
------ ------------ ------------ -------- SID	LINEORDER	TABLE	30407.75
SID	CUSTOMER	TABLE	168
SID	PART	TABLE	120

本篇文章所有的測試,除非特別的說明,我關閉了12c的adaptive plan特性,引數optimizer_adaptive_features被預設設定為false。Adaptive相關的特性如cardinality feedback,adaptive distribution method,adaptive join都不會啟用。如果檢查執行計劃的outline資料,你會發現7個優化器相關的隱含引數被設定為關閉狀態。事實上,12c優化器因為引入adaptive plan特性,比以往版本複雜得多,剖析12c的優化器的各種新特性,我覺得非常具有挑戰性,或許我會在另一篇文章裡嘗試一下。 

select * from table(dbms_xplan.display_cursor('77457qc9a324k',0,’outline’));
...
Outline Data
-------------
/*+
BEGIN_OUTLINE_DATA
IGNORE_OPTIM_EMBEDDED_HINTS
OPTIMIZER_FEATURES_ENABLE('12.1.0.2')
DB_VERSION('12.1.0.2')
OPT_PARAM('_optimizer_use_feedback' 'false')
OPT_PARAM('_px_adaptive_dist_method' 'off')
OPT_PARAM('_optimizer_dsdir_usage_control' 0)
OPT_PARAM('_optimizer_adaptive_plans' 'false')
OPT_PARAM('_optimizer_strans_adaptive_pruning' 'false')
OPT_PARAM('_optimizer_gather_feedback' 'false')
OPT_PARAM('_optimizer_nlj_hj_adaptive_join' 'false')
OPT_PARAM('optimizer_dynamic_sampling' 11)
ALL_ROWS
……
END_OUTLINE_DATA
*/

並行初體驗

序列執行

以下sql對customers和lineorder連線之後,計算所有訂單的全部利潤。 序列執行時不使用parallel hint:

select /*+ monitor */
sum(lo_revenue)
from
lineorder, customer
where
lo_custkey = c_custkey;

序列執行時,sql執行時間為1.5分鐘,dbtime為1.5分鐘。執行計劃有5行,一個使用者程序工作完成了對customer,lineorder兩個表的掃描,hashjoin,聚合以及返回資料的所有操作。此時AAS(average active sessions)為1,sql執行時間等於db time。幾乎所有的dbtime都為db cpu,72%的cpu花在了第二行的hash join操作。因為測試機器為一臺Exadata X3——8,30GB的IO請求在一秒之內處理完成。Celloffload Efficiency等於87%意味著經過儲存節點掃描,過濾不需要的列,最終返回計算節點的資料大小隻有30GB的13%。


並行執行

使用hint parallel(4),指定DoP=4並行執行同樣的sql: 

select /*+ monitor parallel(4)*/
sum(lo_revenue)
from
lineorder, customer
where
lo_custkey = c_custkey;

SQL執行時間為21s,db time為1.4分鐘。DoP=4,在兩個例項上執行。執行計劃從5行增加為9行,從下往上分別多了’PXBLOCKITERATOR’, ‘SORTAGGREGATE’, ‘PXSENDQC(RANDOM)’ 和 ’PXCOORDINATOR’ 這四個操作。

其中3到8行的操作為並行處理,sql的執行順序為:每個PX程序掃描維度表customer(第6行),以資料塊地址區間作為單位(第7行)掃描四分之一的事實表lineorder(第8行),接著進行hash join(第5行),然後對連線之後的資料做預先聚合(第4行),最後把結果給QC(第三行)。QC接收資料(第2行)之後,做進一步的彙總(第1行),最後返回資料(第0行)。

SQL執行時間比原來快了4倍,因為最消耗時間的操作,比如對lineorder的全表掃描,hashjoin和聚合,我們使用4個程序並行處理,因此最終sql執行時間為序列執行的1/4。另一方面,dbtime並沒有明顯下降,並行時1.4m,序列時為1.5m,從系統的角度看,兩次執行消耗的系統資源是一樣的。

                

DoP=4時,因為沒有涉及資料的分發(distribution),QC只需分配一組PX程序,四個PX程序分別為例項1和2的p000/p0001。我們可以從系統上檢視這4個PX程序。每個PX程序消耗大致一樣的db time,CPU和IO資源。AAS=4,這是最理想的情況,每個PX程序完成同樣的工作量,一直保持活躍。沒有序列點,沒有並行執行傾斜。

AAS=4,檢視活動資訊時,為了更好的展示活動資訊,注意點掉”CPU Cores”這個複選框。 

 

在Linux系統上顯示這四個PX程序。 

[[email protected] sidney]$ ps -ef | egrep "p00[01]_SSB"
oracle 20888 1 4 2014 ? 18:50:59 ora_p000_SSB1
oracle 20892 1 4 2014 ? 19:01:29 ora_p001_SSB1
[[email protected] sidney]$ ssh exa01db02 'ps -ef | egrep "p00[01]_SSB"'
oracle 56910 1 4 2014 ? 19:01:03 ora_p000_SSB2
oracle 56912 1 4 2014 ? 18:53:30 ora_p001_SSB2

小結

本節的例子中,DoP=4,並行執行時分配了4個PX程序,帶來4倍的效能提升。SQL monitor報告包含了並行執行的總體資訊和各種細節,比如QC,DoP,並行執行所在的例項,每個PX程序消耗的資源,以及執行SQL時AAS。

生產者-消費者模型

在上面並行執行的例子中,每個px程序都會掃描一遍維度表customer,然後掃描事實表lineorder進行hash join。這時沒有資料需要進行分發,只需要分配一組px程序。這種replicate維度表的行為,是12c的新特性,由引數_px_replication_enabled控制。

更常見情況是並行執行時,QC需要分配兩組PX程序,互為生產者和消費者協同工作,完成並行執行計劃。架構圖1如下:

               

Broadcast分發,一次資料分發

為了舉例說明兩組px程序如何協作的,設定_px_replication_enabled為false。QC會分配兩組PX程序,一組為生產者,一組為消費者。

見下圖,此時sql執行時間為23s,執行時間變慢了2s,dbtime仍為1.5分鐘。

              

最大的變化來自執行計劃,現在執行計劃有12行。增加了對customer的並行掃描 PXBLOCKITERATOR (第8行),分發’PXSENDBROADCAST’和接收’PXRECEIVE’。執行計劃中出現了兩組PX程序,除了之前藍色的多人標誌,現在出現了紅色的多人標誌。此時,SQL的執行順序為:

  1. 4個紅色的PX程序扮演生產者角色,掃描維度表customer,把資料通過broadcast的方式分發給每一個扮演消費者的藍色PX程序。因為DoP=4,每一條被掃描出來的記錄被複制了4份,從sqlmonitor的第9行,customer全表掃描返回1。5m行資料,第8行的分發和第7行的接受之時,變成了6m行記錄,每個作為消費者的藍色px程序都持有了一份完整包含所有custome記錄的資料,並準備好第5行hashjoin的buildtable。
  2. 4個作為消費者的藍色PX程序,以資料塊地址區間為單位掃描事實表lineorder(第10/11行);同時和已經持有的customer表的資料進hashjoin(第5行),然後對滿足join條件的資料做預聚合(第4行),因為我們查詢的目標是對所有lo_revenue求和,聚合之後每個PX程序只需輸出一個總數。
  3. 4個藍色的PX程序反過來作為生產者,把聚合的資料發給消費者QC(第3行和第2行)。由QC對接收到4行記錄做最後的聚合,然後返回給使用者。
  4. 使用broadcast的分發方式,只需要把customer的資料廣播給每個消費者。Lineorder的數不需要重新分發。因為lineorder的資料量比customer大的多,應該避免對lineorder的資料進行分發,這種執行計劃非常適合星型模型的資料。
                 

觀察sql monitor報告中Parallel標籤下的資訊,紅色的PX程序為例項1、2上的p002/p003程序,藍色的PX程序為p000/p001程序,因為藍色的PX程序負責掃描事實表lineorder,hash join和聚合,所以消耗幾乎所有的db time。 

                 

生產者-消費者模型工作原理

並行查詢之後,可以通過檢視V$PQ_TQSTAT,驗證以上描述的執行過程。

  1. 例項1、2上的p002/p003程序作為生產者,幾乎平均掃描customer的1/4記錄,把每一條記錄廣播給4個消費者PX程序,傳送的記錄數之和為6m行。通過table queue0(TQ_ID=0),每個作為消費者的p000/p001程序,接收了完整的1。5m行customer記錄,接收的記錄數之和為 6m行。
  2. 例項1、2上的p000/p0001程序作為生產者,通過table queue1(TQ_ID=1),把聚合的一條結果記錄發給作為消費者的QC。QC作為消費者,接收了4行記錄。
SELECT
dfo_number, tq_id, server_type, instance, process, num_rows
FROM
V$PQ_TQSTAT
ORDER BY
dfo_number DESC, tq_id, server_type desc, instance, process;
DFO_NUMBER TQ_ID SERVER_TYPE INSTANCE PROCESS NUM_ROWS
---------- ---------- -------------- ---------- --------- ----------
1 0 Producer 1 P002 1461932
1 0 Producer 1 P003 1501892
1 0 Producer 2 P002 1575712
1 0 Producer 2 P003 1460464
1 0 Consumer 1 P000 1500000
1 0 Consumer 1 P001 1500000
1 0 Consumer 2 P000 1500000
1 0 Consumer 2 P001 1500000
1 1 Producer 1 P000 1
1 1 Producer 1 P001 1
1 1 Producer 2 P000 1
1 1 Producer 2 P001 1
1 1 Consumer 1 QC 4
13 rows selected.

那麼,以上的輸出中,DFO_NUMBER和TQ_ID這兩列表示什麼意思呢?

  1. DFO代表Data Flow Operator,是執行計劃中可以並行執行的操作。一個QC代表一棵DFO樹(tree),包含多個DFO;同一個QC中所有並行操作的DFO_NUMBER是相同的,此例中,所有DFO_NUMBER為1。執行計劃包含多個QC的例子也不少見,比如使用unionall的語句,unionall每個分支都是獨立的DFO樹,不同的DFO樹之間可以並行執行。本篇文章僅討論執行計劃只有一個QC的情況。
  2. TQ代表table queue,用以PX程序之間或者和QC通訊連線。以上執行計劃中,table queue0為PX程序之間的連線,table queue1為PX程序和QC之間的連線。生產者通過table queue分發資料,消費者從tablequeue接收資料。不同的table queue編號,代表了不同的資料分發。通過table queue,我們可以理解Oracle並行執行使用生產者-­‐消費者模型的本質:
  • 同一棵DFO樹中,最多隻有兩組PX程序。每個生產者程序都存在一個和每個消費者程序的連線,每個PX程序和QC都存在一個連線。假設DoP=n,連線總數為(n*n+2*n),隨著n的增長,連線總數會爆炸型增長。Oracle並行執行設計時,採用生產者和消費者模型,考慮到連線數的複雜度,每個DFO最多隻分配兩組PX程序。假設DoP=100時,兩組PX程序之間的連線總數為10000。假設可以分配三組PX程序一起完成並行執行計劃,那麼三組PX之間連線總數會等於1百萬,維護這麼多連線,是一個不可能的任務。
  • 同一棵DFO樹中,兩組PX程序之間,同一時間只存在一個活躍的資料分發。如果執行路徑很長,資料需要多次分發,兩組PX程序會變換生產者消費者角色,相互協作,完成所有並行操作。每次資料分發,對應的tablequeue的編號不同。一個活躍的資料分發過程,需要兩組PX程序都參與,一組為生產者傳送資料,一組為消費者接收資料。因為一個DFO裡最多隻有兩組PX程序,意味著,PX程序之間,同一時間只能有一個活躍的資料分發。如果PX程序在執行計劃中需要多次分發資料,可能需要在執行計劃插入一些阻塞點,比如BUFFERSORT和HASHJOINBUFFERED這兩個操作,保證上一次的資料分發完成之後,才開始下一次分發。在後面的章節,我將會說明這些阻塞點帶來什麼影響。這個例子中,tablequeue0和1可以同時工作是因為:tablequeue0是兩組PX程序之間的連結,tablequeue1為PX程序和QC之間的連線,tablequeue0與tablequeue1是相互獨立的,因此 可以同時進行。
  • PX程序之間或者與QC的連線至少存在一個(單節點下至多三個,RAC環境下至多四個)訊息緩衝區用於程序間資料互動,該訊息緩衝區預設在Largepool中分配(如果沒有配置Largepool則在Sharedpool中分配)。多個緩衝區是為了實現非同步通訊,提高效能。
  • 每個訊息緩衝區的大小由引數parallel_execution_message_size控制,預設為16k。
  • 當兩個程序都在同一個節點的時候,通過在Largepool(如果沒有配置Largepool則Sharedpool)中傳遞和接收訊息緩衝進行資料互動。當兩個程序位於不同節點時。通過RAC心跳網路進行資料互動,其中一方接收的資料需要快取在本地Largepool(如果沒有配置Largepool則Sharedpool)裡面。

小結

為了說明並行執行的生產者--消費者模型是如何工作的,我使用了broad cast分發,QC分配兩組PX程序,一組為生產者,一組為消費者。QC和PX程序之間,兩組PX程序之間通過table queue進行資料分發,協同完成整個並行執行計劃。檢視V$PQ_TQSTAT記錄了並行執行過程中,資料是如何分發的。通過對DFO,table queue的描述,我闡述生產者-­‐消費者模型的工作原理和通訊過程,或許有些描述對你來說過於突然,不用擔心,後面的章節我會通過更多的例子來輔助理解。

如何閱讀並行執行計劃

Table queue 的編號代表了並行執行計劃中,資料分發的順序。理解執行計劃中的並行操作是如何被執行的,原則很簡單:跟隨Tablequeue的順序。 

通過sqlmonitor報告判斷sql的執行順序,需要結合name列的tablequeue名字比如:TQ10000(代表DFO=1,tablequeue0),:TQ10001(代表DFO=1,tablequeue1),還有PX程序的顏色,進行確定。

下面的例子為dbms_xplan。display_cursor 的輸出。對於並行執行計劃,會多出來三列: 

1. TQ列:為Q1:00或者Q1:01,其中Q1代表第一個DFO,00或者01代表tablequeue的編號。

a. ID7~9的操作的TQ列為Q1,00,該組PX程序,作為生產者首先執行,然後通過broadcast 的分發方式,把資料發給消費者。

b. ID10~11,3~6的操作的TQ列為Q1,01,該組PX程序作為消費者接受customer的資料之後,掃描lineorder,hashjoin,聚合之後,又作為生產者通過tablequeue2把資料 發給QC。

2. In-­‐out 列:表明資料的流動和分發。

      •PCWC:parallelcombinewithchild

      •PCWP:parallelcombinewithparent

      •P-­‐>P:  paralleltoparallel。

      •P-­‐>S:  paralleltoSerial。

3. PQDistribute 列:資料的分發方式。此執行計劃中,我們使用了broadcast 的方式,下面的章節

    我會講述其他的分發方式。


HASH分發方式, 兩次資料分發

除了broadcast分發方式,另一種常見的並行分發方式為hash。為了觀察使用hash分發時sql的 執行情況,我對sql使用pq_distributehint 

select /*+ monitor parallel(4)
         leading(customer lineorder)
         use_hash(lineorder)
         pq_distribute(lineorder hash hash) */
    sum(lo_revenue)
from
    lineorder, customer
where
    lo_custkey = c_custkey;

使用hash分發方式時,sql的執行時間為29s,dbtime為2.6m。相對於broadcast方式,sql的執行時間和dbtime都增加了大約40%。

執行計劃如下,執行計劃為14行,增加了對lineorder的hash分發,第11行的’PXSENDHASH’對3億行資料通過hash函式分發,第10行的’PXRECEIVE’通過tablequeue1接收3億行資料,這兩個操作消耗了38%的dbcpu。這就是為什麼SQL執行時間和dbtime變長的原因。此時,SQL的執行順序為:

  1. 紅色的PX程序作為生產者,並行掃描customer(第8~9行),對於連線鍵c_custkey運用函式,根據每行記錄的hash值,通過table queue0,發給4個藍色消費者的其中一個(第7行)。Hash分發方式並不會複製資料,sql monitor報告的第6~9行,actual rows列都為1.5m。
  2. 紅色的PX程序作為生產者,並行掃描li neorder(第12~13行),對於連線鍵l o_custkey運用同樣的dhash函式,通過tablequeue1 ,發給4個藍色消費者的其中一個(第11行)。同樣的hash函式保證了customer和li neorder相同的連線鍵會發給同一個消費者,保證hashj oin結果的正確。因為3億行資料都需要經過hash函式計算,然後分發(這是程序間的通訊,或者需要通過RAC心跳網路通訊),這些巨大的額外開銷,就是增加38% cpu的原因。
  3. 4個藍色的PX程序作為消費者接收了customer的1.5M行記錄(第 6 行),和lineorder的3億行記錄(第10行),進行hash join(第5行),預聚合(第4行)。

  4. 4個藍色的PX程序反過來作為生產者,通過table queue2,把聚合的資料發給消費者QC(第3 行和第2行)。由QC對接收到4行記錄做最後的聚合, 然後返回給使用者(第1和0行)。

觀察sql monitor報告中Parallel標籤下的資訊,紅色的px程序為例項1、2上的p002/p003程序,藍色的PX程序為p000/p001程序。作為生產者的紅色PX程序負責掃描事實表lineorder,對3億行資料進行hash分發,佔了超過1/3的db time。 

 

因為涉及3億行資料的分發和接收,作為生產者的紅色PX程序和作為消費者的藍色PX程序需要同時活躍,SQL monitor報告中的activity資訊顯示大部分時間,AAS超過並行度4,意味這兩組PX程序同時工作。不像replicate或者broadcast分發時,AAS為4,只有一組PX程序保持活躍。 

 

SELECT
dfo_number, tq_id, server_type, instance, process, num_rows
FROM
V$PQ_TQSTAT
ORDER BY
dfo_number DESC, tq_id, server_type desc, instance, process;
DFO_NUMBER TQ_ID SERVER_TYPE INSTANCE PROCESS NUM_ROWS
---------- ---------- -------------- ---------- --------- ----------
1 0 Producer 1 P002 299928364
1 0 Producer 1 P003 299954384
1 0 Producer 2 P002 300188788
1 0 Producer 2 P003 299951708
1 0 Consumer 1 P000 300005811
1 0 Consumer 1 P001 300005811
1 0 Consumer 2 P000 300005811
1 0 Consumer 2 P001 300005811
1 1 Producer 1 P000 1
1 1 Producer 1 P001 1
1 1 Producer 2 P000 1
1 1 Producer 2 P001 1
1 1 Consumer 1 QC 4
13 rows selected.
select /*+ monitor parallel(4)*/
sum(lo1.lo_revenue)
from
lineorder_hash32 lo1, lineorder_hash32 lo2
where
lo1.lo_orderkey = lo2.lo_orderkey;

並行查詢之後,通過檢視V$PQ_TQSTAT,進一步驗證以上描述的執行過程。並行執行過程涉及3

個tablequeue0/1/2,V$PQ_TQSTAT包含21行記錄。

1. 例項1、2上的p002/p003程序作為生產者,平均掃描customer的1/4記錄,然後通過tablequeue0(TQ_ID=0),發給作為消費者的p000/p001程序。傳送和接收的customer記錄之和都為 1.5m。

        •  傳送的記錄數:1500000= 365658+364899+375679+393764

        •  接收的記錄數:1500000= 374690+374924+375709+374677

2.  例項1、2上的p002/p0003程序作為生產者,平均掃描lineorder的1/4記錄,通過table queue1(TQ_ID=1) ,發給作為消費者的p000/p001程序。傳送和接收的lineorder 記錄之和都為300005811。

        •  傳送的記錄數:300005811= 74987629+75053393+74979748+74985041 

        •  接收的記錄數:300005811= 74873553+74968719+75102151+75061388

3. 例項1、2上的p000/p0001程序作為生產者,通過tablequeue2(TQ_ID=2),把聚合的一條結果記 錄發給作為消費者的QC。QC作為消費者,接收了4行記錄。  

SELECT
dfo_number, tq_id, server_type, instance, process, num_rows
FROM
V$PQ_TQSTAT
ORDER BY
dfo_number DESC, tq_id, server_type desc, instance, process;
DFO_NUMBER TQ_ID SERVER_TYPE INSTANCE PROCESS NUM_ROWS
---------- ---------- ---------------- ---------- --------- ----------
1 0 Producer 1 P002 365658
1 0 Producer 1 P003 364899
1 0 Producer 2 P002 375679
1 0 Producer 2 P003 393764
1 0 Consumer 1 P000 374690
1 0 Consumer 1 P001 374924
1 0 Consumer 2 P000 375709
1 0 Consumer 2 P001 374677
1 1 Producer 1 P002 74987629
1 1 Producer 1 P003 75053393
1 1 Producer 2 P002 74979748
1 1 Producer 2 P003 74985041
1 1 Consumer 1 P000 74873553
1 1 Consumer 1 P001 74968719
1 1 Consumer 2 P000 75102151
1 1 Consumer 2 P001 75061388
1 2 Producer 1 P000 1
1 2 Producer 1 P001 1
1 2 Producer 2 P000 1
1 2 Producer 2 P001 1
1 2 Consumer 1 QC 4
21 rows selected.

小結

陣列大小m,可以把錯誤判斷的機率控制在很小的範圍之內。

我們觀察hash分發時sql的並行執行過程。Hash分發與broadcast最大的區分在於對hashjoin的 兩邊都進行分發。這個例子中,對lineorder 的hash分發會增加明顯的dbcpu 。下一節,我將使用另一個例子,說明hash分發適用的場景。

Replicate,Broadcast和Hash的選擇

我們已經測試過replicate,broadcast,和hash這三種分發方式。

  1. Replicate :每個PX程序重複掃描hashjoin 的左邊,buffercache 被用來快取hashjoin 左邊的小表,減少重複掃描所需的物理讀。相對於broadcast 分發,replicate 方式只需一組PX程序。但是repli cate不能替換br oadcast分發。因為repli cate僅限於hashj oin左邊是表的情況,如果hashjoin的左邊的結果集來自其他操作,比如j oin或者檢視,那麼此時無法使用repli cate
  2. Broadcast分發:作為生產者的PX程序通過廣播的方式,把hashjoin左邊的結果集分發給每 個作為消費者的PX程序。一般適用於hashjoin 左邊結果集比右邊小得多的場景,比如星型模型。

  3. Hash分發的本質:把hashjoin的左邊和右邊(兩個資料來源),通過同樣hash函式重新分發,切 分為N個工作單元(假設DoP=N),再進行join ,目的是減少PX程序進行join 操作時,需要連線的資料量。Hash分發的代價需要對hashjoin 的兩邊都進行分發。對於customer連線li neorder的例子,因為維度表customer的資料量比事實表li neorder小得多,對customer進行repli cate或者broadcast 分發顯然是更好的選擇,因為這兩種方式不用對li

    相關推薦

    陳煥生:深入理解Oracle並行執行

    Oracle並行執行是一種分而治之的方法。執行一個sql 時,分配多個並行程序同時執行資料掃描,連線以及聚合等操作,使用更多的資源,得到更快的sql 響應時間。並行執行是充分利用硬體資源,處理大量資料時的核心技術。 在本文中,在一個簡單的星型模型上,我會使用大量

    深入理解Oracle並行執行

    Oracle並行執行是一種分而治之的方法。執行一個sql 時,分配多個並行程序同時執行資料掃描,連線以及聚合等操作,使用更多的資源,得到更快的sql 響應時間。並行執行是充分利用硬體資源,處理大量資料時的核心技術。  在本文中,在一個簡單的星型模型上,我

    oracle 並行執行sql

    tps com parallel 裏的 att 並行執行 SQ 並行 logs 具體查詢語法,在select 後面 添加 /*+PARALLEL */ 這裏的/*+PARALLEL */ 是提示oracle 使用 並行方式去執行查詢sql, 使用hint語句註意事項

    深入理解Java程式執行順序

    下面將從一道阿里巴巴試題詳細分析Java程式執行順序。 阿里巴巴試題 public class Test { public static int k = 0; public static Test t1 = new Test("t1"); public static Test t

    深入理解java多執行緒(六)

    關於java多執行緒的概念以及基本用法:java多執行緒基礎 6,單例模式與多執行緒 如何使單例模式遇到多執行緒是安全的這是下面要討論的內容 6.1,立即載入 立即載入就是在使用類的時候已經將物件建立完畢,例如String s = new Stri

    深入理解Java多執行緒(五)

    關於java多執行緒的概念以及基本用法:java多執行緒基礎 5,定時器Timer JDK中Timer類主要是負責計劃任務的功能,也就是在指定的時間開始執行某一個任務,封裝任務的類是TimerTask類,執行計劃任務的程式碼要放進TimerTask的子類,因為它一個抽象

    深入理解Java多執行緒(四)

    關於java多執行緒的概念以及基本用法:java多執行緒基礎 4,Lock的使用 ReentrantLook類的使用 ReentrantReadWriteLock類的使用 4.1,ReentrantLook類的使用 新建MySe

    深入理解Java多執行緒(三)

    關於java多執行緒的概念以及基本用法:java多執行緒基礎 3, 執行緒間通訊 執行緒在作業系統中是獨立的個體,經過特殊的處理,執行緒間可以實現通訊,進而成為一個整體,提高CPU利用率 3.1,等待/通知機制 等待:wait()方法作用是使當前執

    深入理解Java多執行緒(二)

    關於java多執行緒的概念以及基本用法:java多執行緒基礎 2,多執行緒的同步 多個執行緒對同一物件的變數進行同時訪問時會引發執行緒的安全問題,即一個執行緒對一個變數修改後,其他執行緒可能會讀取到修改後的變數值,所以我們要對獲得的例項變數的值進行同步處理,保證其原子性

    深入理解Java多執行緒(一)

    關於java多執行緒的概念以及基本用法:java多執行緒基礎 1,停止執行緒 停止執行緒意味著線上程執行完之前停止正在做的操作,即立刻放棄當前的操作,這並不容易。停止執行緒可以用Thread.stop()方法,但是這個方法不安全,所以不建議使用,還有一個方法就是Thre

    深入理解java:執行緒本地變數 java.lang.ThreadLocal類

    ThreadLocal,很多人都叫它做執行緒本地變數,也有些地方叫做執行緒本地儲存,其實意思差不多。 可能很多朋友都知道ThreadLocal為變數在每個執行緒中都建立了一個副本,那樣每個執行緒可以訪問自己內部的副本變數。 這句話從表面上看起來理解正確,但實際上這種理解是不太正確的。下面我們

    併發程式設計之美,帶你深入理解java多執行緒原理

    1.什麼是多執行緒? 多執行緒是為了使得多個執行緒並行的工作以完成多項任務,以提高系統的效率。執行緒是在同一時間需要完成多項任務的時候被實現的。 2.瞭解多執行緒 瞭解多執行緒之前我們先搞清楚幾個重要的概念! 如上圖所示:對我們的專案有一個主記憶體,這個主記憶體裡面存放了我們的共享變數、方法區、堆中的物件等

    深入理解Java多執行緒--執行緒池(ThreadPool)

    在java多執行緒開發中,我們需要使用執行緒的時候一般是建立一個Thread物件,然後呼叫start()方法去執行執行緒操作。這樣做沒有什麼問題,但是如果我們有很多工需要多個執行緒來非同步執行的時候,在我們建立了很多執行緒的情況下,會造成很大的效能方面的問題。 1.大量的執行緒的建立和銷燬,

    深入理解Java多執行緒--synchronized的實現原理

    執行緒安全是多執行緒程式設計中的一個重要的知識點,何為執行緒安全?在多執行緒併發中,有很多資料是執行緒共享的,當我們某個執行緒去操作共享資料的時候,需要先將共享資料複製到當前執行緒的記憶體空間中來,然後進行操作完畢之後再將資料更新到共享空間中去。這就造成了一個問題,當我們有多個執行緒去讀取和操作

    深入理解併發/並行,阻塞/非阻塞,同步/非同步 同步與阻塞,非同步與非阻塞的區別

    同步與非同步是對應的,它們是執行緒之間的關係,兩個執行緒之間要麼是同步的,要麼是非同步的。阻塞與非阻塞是對同一個執行緒來說的,在某個時刻,執行緒要麼處於阻塞,要麼處於非阻塞。阻塞是使用同步機制的結果,非阻塞則是使用非同步機制的結果。 深入理解併發/並行,阻塞/非阻塞,同步/非同步 1. 阻塞,非

    深入理解JS立即執行函式

    1.什麼是立即執行函式(IIFE) 在瞭解立即執行函式之前先明確一下函式宣告、函式表示式及匿名函式的形式,如下圖: 接下來看立即執行函式的兩種常見形式: ( function(){…} )()  和  ( function (){…} () ) ,一個是一個匿名函式包裹在一個括號運

    深入理解JavaScript的執行機制(同步和非同步)

    不論是面試求職,還是日常開發工作,我們經常會遇到這樣的情況:給定的幾行程式碼,我們需要知道其輸出內容和順序。因為JavaScript是一門單執行緒語言,所以我們可以得出結論: JavaScript是按照語句出現的順序執行的 所以我們以為JS都是這樣的:

    深入理解併發/並行,阻塞/非阻塞,同步/非同步

    1. 阻塞,非阻塞 首先,阻塞這個詞來自作業系統的執行緒/程序的狀態模型中,如下圖: 一個執行緒/程序經歷的5個狀態,建立,就緒,執行,阻塞,終止。各個狀態的轉換條件如上圖,其中有個阻塞狀態,就是說當執行緒中呼叫某個函式,需要IO請求,或者暫時得不到競爭

    深入理解Oracle表(5):三大表連線方式詳解之Hash Join的定義,原理,演算法,成本,模式和點陣圖

     Hash Join只能用於相等連線,且只能在CBO優化器模式下。相對於nested loop join,hash join更適合處理大型結果集        Hash Join的執行計劃第1個是hash表(build table),第2個探查表(probe table),

    深入理解Oracle中的shared pool與library cache元件及相關等待事件

    傳統的’library cache pin’在10.2.0.2之後預設被取代, 此處PIN被Mutex及其ref count取代。 當程序執行遊標語句時或者需要PIN,或者需要hard parse一個子遊標heap。在版本10.2.0.1中, 使用mutex部分程式碼替代PIN的功能預設是不啟用的,