W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
因?yàn)槊總€(gè)工作者只執(zhí)行完成計(jì)劃的并行部分,所以不可能簡單地產(chǎn)生一個(gè)普通查詢計(jì)劃并使用多個(gè)工作者運(yùn)行它。每個(gè)工作者都會產(chǎn)生輸出結(jié)果集的一個(gè)完全拷貝,因而查詢并不會比普通查詢運(yùn)行得更快甚至還會產(chǎn)生不正確的結(jié)果。相反,計(jì)劃的并行部分一定被查詢優(yōu)化器在內(nèi)部當(dāng)作一個(gè)部分計(jì)劃,即它必須被構(gòu)建出來,這樣每一個(gè)執(zhí)行該計(jì)劃的進(jìn)程將以無重復(fù)地方式產(chǎn)生輸出行的一個(gè)子集,即保證每一個(gè)所需要的輸出行正好只被一個(gè)合作進(jìn)程生成。通常,這意味著該查詢的驅(qū)動(dòng)表上的掃描必須是一種可并行的掃描。
當(dāng)前支持下列可并行的表掃描。
在一個(gè)并行順序掃描中,表塊將在合作進(jìn)程之間被劃分。一次會分發(fā)一個(gè)塊,這樣對表的訪問還是保持順序方式。
在一個(gè)并行位圖堆掃描中,一個(gè)進(jìn)程被選為領(lǐng)導(dǎo)者。這個(gè)進(jìn)程執(zhí)行對一個(gè)或者多個(gè)索引的掃描并且構(gòu)建出一個(gè)位圖指示需要訪問哪些表塊。這些表塊接著會在合作進(jìn)程之間劃分(和并行順序掃描中一樣)。換句話說,堆掃描以并行方式進(jìn)行但底層的索引掃描不是并行。
在一個(gè)并行索引掃描或者并行只用索引的掃描中,合作進(jìn)程輪流從索引讀取數(shù)據(jù)。當(dāng)前,并行索引掃描僅有B-樹索引支持。每一個(gè)進(jìn)程將認(rèn)領(lǐng)一個(gè)索引塊并且掃描和返回該索引塊引用的所有元組,其他進(jìn)程可以同時(shí)地從一個(gè)不同的索引塊返回元組。并行B-樹掃描的結(jié)果會以每個(gè)工作者進(jìn)程內(nèi)的順序返回。
其他掃描類型(例如非B-樹索引的掃描)可能會在未來支持并行掃描。
正如在非并行計(jì)劃中那樣,驅(qū)動(dòng)表可能被使用嵌套循環(huán)、哈希連接或者歸并連接連接到一個(gè)或者多個(gè)其他表。連接的內(nèi)側(cè)可以是任何類型的被規(guī)劃器支持的非并行計(jì)劃,假設(shè)它能夠安全地在并行工作者中運(yùn)行。根據(jù)連接類型,內(nèi)側(cè)還可以是一種并行計(jì)劃。
在一個(gè)嵌套循環(huán)連接中,內(nèi)側(cè)總是非并行的。盡管它會被完全執(zhí)行,如果內(nèi)側(cè)是一個(gè)索引掃描也會很高效,因?yàn)橥鈧?cè)元組以及在索引中查找值的循環(huán)會被劃分到多個(gè)合作進(jìn)程。
在一個(gè)歸并連接中,內(nèi)側(cè)總是一個(gè)非并行計(jì)劃并且因此會被完全執(zhí)行。這可能是不太高效的,特別是在排序必須被執(zhí)行時(shí),因?yàn)樵诿恳粋€(gè)合作進(jìn)程中工作數(shù)據(jù)和結(jié)果數(shù)據(jù)是重復(fù)的。
在一個(gè)哈希連接(沒有“并行”前綴)中,每個(gè)合作進(jìn)程都會完全執(zhí)行內(nèi)側(cè)以構(gòu)建哈希表的相同拷貝。如果哈希表很大或者該計(jì)劃開銷很大,這種方式就很低效。在一個(gè)并行哈希連接中,內(nèi)側(cè)是一個(gè)并行哈希,它把構(gòu)建共享哈希表的工作劃分到多個(gè)合作進(jìn)程。
PostgreSQL通過按兩個(gè)階段進(jìn)行聚集來支持并行聚集。首先,每個(gè)參與到查詢并行部分的進(jìn)程執(zhí)行一個(gè)聚集步驟,為該進(jìn)程注意到的每個(gè)分組產(chǎn)生一個(gè)部分結(jié)果。這在計(jì)劃中反映為一個(gè)Partial Aggregate
節(jié)點(diǎn)。然后,部分結(jié)果通過Gather
或者Gather Merge
被傳輸?shù)筋I(lǐng)導(dǎo)者。最后,領(lǐng)導(dǎo)者對來自所有工作者的結(jié)果進(jìn)行重新聚集得到最終的結(jié)果。這在計(jì)劃中反映為一個(gè)
Finalize Aggregate
節(jié)點(diǎn)。
因?yàn)?code class="literal">Finalize Aggregate節(jié)點(diǎn)運(yùn)行在領(lǐng)導(dǎo)者進(jìn)程上,如果查詢產(chǎn)生的分組數(shù)相對于其輸入行數(shù)來說比較大,則查詢規(guī)劃器不會喜歡它。例如,在最壞的情況下,Finalize Aggregate
節(jié)點(diǎn)看到的分組數(shù)可能與所有工作者進(jìn)程在Partial Aggregate
階段看到的輸入行數(shù)一樣多。對于這類情況,使用并行聚集顯然得不到性能收益。查詢規(guī)劃器會在規(guī)劃過程中考慮這一點(diǎn)并且不太會在這種情況下選擇并行聚集。
并行聚集并非在所有情況下都被支持。每一個(gè)聚集都必須是對并行安全的并且必須有一個(gè)組合函數(shù)。如果該聚集有一個(gè)類型為internal
的轉(zhuǎn)移狀態(tài),它必須有序列化和反序列化函數(shù)。更多細(xì)節(jié)請參考
CREATE AGGREGATE
。如果任何聚集函數(shù)調(diào)用包含DISTINCT
或ORDER BY
子句,則不支持并行聚集。對于有序集聚集或者當(dāng)查詢涉及GROUPING SETS
時(shí),也不支持并行聚集。只有在查詢中涉及的所有連接也是該計(jì)劃并行部分的組成部分時(shí),才能使用并行聚集。
只要當(dāng)PostgreSQL需要從多個(gè)源中整合行到一個(gè)單一結(jié)果集時(shí),它會使用Append
或MergeAppend
計(jì)劃節(jié)點(diǎn)。在實(shí)現(xiàn)UNION ALL
或掃描分區(qū)表時(shí)常常會發(fā)生這種情況。就像這些節(jié)點(diǎn)可以被用在任何其他計(jì)劃中一樣,它們可以被用在并行計(jì)劃中。不過,在并行計(jì)劃中,規(guī)劃器使用的是
Parallel Append
節(jié)點(diǎn)。
當(dāng)一個(gè)Append
節(jié)點(diǎn)被用在并行計(jì)劃中時(shí),每個(gè)進(jìn)程將按照子計(jì)劃出現(xiàn)的順序執(zhí)行子計(jì)劃,這樣所有的參與進(jìn)程會合作執(zhí)行第一個(gè)子計(jì)劃直到它被完成,然后同時(shí)移動(dòng)到第二個(gè)計(jì)劃。而在使用Parallel Append
時(shí),執(zhí)行器將把它的子計(jì)劃盡可能均勻地散布在參與進(jìn)程中,這樣多個(gè)子計(jì)劃會被同時(shí)執(zhí)行。這避免了競爭,也避免了子計(jì)劃在那些不執(zhí)行它的進(jìn)程中產(chǎn)生啟動(dòng)代價(jià)。
此外,和常規(guī)的Append
節(jié)點(diǎn)不同(在并行計(jì)劃中使用時(shí)僅有部分子計(jì)劃),Parallel Append
節(jié)點(diǎn)既可以有部分子計(jì)劃也可以有非部分子計(jì)劃。非部分子計(jì)劃將僅被單個(gè)進(jìn)程掃描,因?yàn)閽呙杷鼈儾恢挂淮螘a(chǎn)生重復(fù)的結(jié)果。因此涉及到追加多個(gè)結(jié)果集的計(jì)劃即使在沒有有效的部分計(jì)劃可用時(shí),也能實(shí)現(xiàn)粗粒度的并行。例如,考慮一個(gè)針對分區(qū)表的查詢,它只能通過使用一個(gè)不支持并行掃描的索引來實(shí)現(xiàn)。規(guī)劃器可能會選擇常規(guī)
Index Scan
計(jì)劃的Parallel Append
。每個(gè)索引掃描必須被單一的進(jìn)程執(zhí)行完,但不同的掃描可以由不同的進(jìn)程同時(shí)執(zhí)行。
enable_parallel_append可以被用來禁用這種特性。
如果我們想要一個(gè)查詢能產(chǎn)生并行計(jì)劃但事實(shí)上又沒有產(chǎn)生,可以嘗試減小parallel_setup_cost或者parallel_tuple_cost。當(dāng)然,這個(gè)計(jì)劃可能比規(guī)劃器優(yōu)先產(chǎn)生的順序計(jì)劃還要慢,但也不總是如此。如果將這些設(shè)置為很小的值(例如把它們設(shè)置為零)也不能得到并行計(jì)劃,那就可能是有某種原因?qū)е虏樵円?guī)劃器無法為你的查詢產(chǎn)生并行計(jì)劃。可能的原因可見 第 15.2 節(jié)和第 15.4 節(jié)。
在執(zhí)行一個(gè)并行計(jì)劃時(shí),可以用EXPLAIN (ANALYZE,VERBOSE)
來顯示每個(gè)計(jì)劃節(jié)點(diǎn)在每個(gè)工作者上的統(tǒng)計(jì)信息。這些信息有助于確定是否所有的工作被均勻地分發(fā)到所有計(jì)劃節(jié)點(diǎn)以及從總體上理解計(jì)劃的性能特點(diǎn)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: