PostgreSQL 并行查询概述
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
PostgreSQL從9.6版本開(kāi)始加入并行查詢,并在PostgreSQL10和PostgreSQL11分別做了大量加強(qiáng)工作。下面從:
- 何時(shí)啟用并行查詢功能
- 并行查詢是如何工作的
- worker進(jìn)程數(shù)量越多,查詢性能越高嗎
?三個(gè)方面簡(jiǎn)單介紹下并行查詢的機(jī)制。
--------------------------------------------------------------------------------
何時(shí)啟用并行查詢功能
? ? 是否啟用并行查詢實(shí)際上有諸多因素決定。總的來(lái)說(shuō),有以下兩個(gè)方面:
- ? ?并行查詢開(kāi)關(guān)等參數(shù)
????????在PostgreSQL系統(tǒng)中,并行查詢的開(kāi)關(guān)是max_parallel_workers_per_gather,它所表示的是單個(gè)Gather節(jié)點(diǎn)所能開(kāi)啟的最大worker進(jìn)程數(shù)量。當(dāng)設(shè)置為0時(shí),是?禁用并行查詢,即沒(méi)有可提供的并行查詢的worker進(jìn)程;該參數(shù)的默認(rèn)值是2,即每個(gè)Gather節(jié)點(diǎn)最多可以有2個(gè)worker進(jìn)程。需要注意的是,postgresql.conf文件中還有一個(gè)名為force_parallel_mode的參數(shù)(看參數(shù)名感覺(jué)像是并行查詢的開(kāi)關(guān)參數(shù)),其實(shí)它表示是否強(qiáng)制開(kāi)啟并行查詢,多用于測(cè)試為目的。如果設(shè)置為on,則無(wú)論何時(shí)都會(huì)進(jìn)行并行查詢(實(shí)際上,這時(shí)并不見(jiàn)得會(huì)帶來(lái)查詢效率的提高,后面會(huì)有介紹),其默認(rèn)值為off,這時(shí)系統(tǒng)會(huì)根據(jù)具體成本考慮是否啟用并行查詢。
????? ? 在并行查詢中,每個(gè)worker進(jìn)程都會(huì)承擔(dān)部分的查詢工作。除了上面說(shuō)的max_parallel_workers_per_gather參數(shù)外,系統(tǒng)還有一個(gè)參數(shù)max_parallel_workers,它決定系統(tǒng)所支持的最大的worker進(jìn)程的數(shù)量,所以max_parallel_workers_per_gather的設(shè)定必須參考max_parallel_workers的值。當(dāng)然,它們都得受限于max_worker_process(系統(tǒng)允許后臺(tái)開(kāi)啟worker進(jìn)程的最大數(shù)量)參數(shù)。
- ? ?并行查詢成本考慮
????? ? 當(dāng)參數(shù)決定可以進(jìn)行并行查詢后,實(shí)際上是否可以進(jìn)行并行查詢,還得進(jìn)行一些成本上的考慮。因?yàn)椴⑿胁樵兂四軒?lái)并行查詢上的效率外,還會(huì)有一些成本的消耗,比如并行帶來(lái)的數(shù)據(jù)分片,進(jìn)程間的通信以及并發(fā)控制所帶來(lái)的的系統(tǒng)的開(kāi)銷等。當(dāng)數(shù)據(jù)量足夠大時(shí),并行查詢帶來(lái)的效率可以抵消這些成本考慮;但是數(shù)據(jù)量比較小時(shí),并行查詢可能不會(huì)帶來(lái)效率的提升,反而會(huì)降低了原有的性能。而對(duì)于并行帶來(lái)的成本,系統(tǒng)需要進(jìn)行計(jì)算其代價(jià),然后決定是否啟用并行查詢。
????? ? 在配置文件中,有專門對(duì)并行查詢成本的設(shè)置:
parallel_tuple_cost = 0.1 # 后天進(jìn)程傳遞tuple的代價(jià)parallel_setup_cost = 1000.0 # worker進(jìn)程的啟動(dòng)成本min_parallel_table_scan_size = 8MB # 并行查詢規(guī)定表的最小數(shù)據(jù)量min_parallel_index_scan_size = 512kB # 并行查詢規(guī)定的索引的最小數(shù)據(jù)量????? ? 系統(tǒng)就是依托上面的參數(shù)進(jìn)行計(jì)算并行查詢的成本。這些參數(shù)基本上采用默認(rèn)值就好,當(dāng)然除非有特殊要求或特殊環(huán)境。
并行查詢是如何工作
? ? 以普通查詢?yōu)槔?#xff0c;下面看一下簡(jiǎn)單查詢的示例:
highgo=# explain analyze select * from test where n = 9999;QUERY PLAN ------------------------------------------------------------------------------------------------------------------------Gather (cost=1000.00..11822.39 rows=3984 width=36) (actual time=2.014..196.880 rows=1 loops=1)Workers Planned: 2Workers Launched: 2-> Parallel Seq Scan on test (cost=0.00..10423.99 rows=1660 width=36) (actual time=76.604..141.282 rows=0 loops=3)Filter: (n = 9999)Rows Removed by Filter: 333333Planning time: 0.044 msExecution time: 196.904 ms (8 行記錄)通過(guò)EXPLAIN可以查看并行查詢的執(zhí)行計(jì)劃。當(dāng)用戶輸入一個(gè)查詢語(yǔ)句時(shí),查詢分析,查詢重寫(xiě)以及查詢規(guī)劃都和原來(lái)一樣,只有到執(zhí)行計(jì)劃時(shí),才開(kāi)始真正進(jìn)入并行查詢環(huán)節(jié)。上面執(zhí)行計(jì)劃中,Gather節(jié)點(diǎn)只是執(zhí)行計(jì)劃的一個(gè)子節(jié)點(diǎn),屬于執(zhí)行計(jì)劃的一部分,當(dāng)查詢執(zhí)行走到Gather節(jié)點(diǎn)時(shí),會(huì)話進(jìn)程會(huì)申請(qǐng)一定數(shù)量的worker進(jìn)程(根據(jù)配置參數(shù),以及成本確定)來(lái)進(jìn)行并行查詢過(guò)程。在這些worker進(jìn)程中,有一個(gè)充當(dāng)leader worker的角色,負(fù)責(zé)收集匯總各個(gè)worker進(jìn)程查詢的結(jié)果。該leader worker進(jìn)程也會(huì)根據(jù)查詢的數(shù)據(jù)量大小承擔(dān)部分的并行查詢部分。執(zhí)行過(guò)程如下圖所示:
?
????? ? Leader worker進(jìn)程和其他worker進(jìn)程通過(guò)動(dòng)態(tài)共享內(nèi)存進(jìn)行通信。其他worker進(jìn)程(包括leader worker進(jìn)程)把分擔(dān)查詢的結(jié)果存儲(chǔ)到共享內(nèi)存中,然后由leader worker進(jìn)程進(jìn)行匯總整個(gè)查詢的結(jié)果。所以需要注意的是,由于并行查詢需要使用了動(dòng)態(tài)共享內(nèi)存,所以dynamic_shared_memory_type參數(shù)需要設(shè)置為none以外的值。
?
worker進(jìn)程數(shù)量越多,查詢性能越高嗎
前面也提到,并不是所有的查詢都能適用于并行查詢。因?yàn)榭紤]到系統(tǒng)的開(kāi)銷以及進(jìn)程占用資源的情況,也并不是開(kāi)啟的worker數(shù)量越多,查詢效率越高。下面以對(duì)同一個(gè)表做同樣的查詢,然后開(kāi)啟不同的worker數(shù)量來(lái)測(cè)試一下。
- 開(kāi)啟 1 個(gè)worker 進(jìn)程
- 開(kāi)啟 2 個(gè)worker 進(jìn)程
- 開(kāi)啟 4 個(gè)worker 進(jìn)程
????????設(shè)置4個(gè)worker,但是實(shí)際上基于成本考慮只啟用了3個(gè)。????
highgo=# explain analyze select * from test where n = 4000000;QUERY PLAN ---------------------------------------------------------------------------------------------Gather (cost=1000.00..43285.39 rows=1 width=4) (actual time=190.967..191.017 rows=1 loops=1)Workers Planned: 3Workers Launched: 3-> Parallel Seq Scan on test (cost=0.00..42285.29 rows=1 width=4) (actual time=174.275..182.767 rows=0 loops=4)Filter: (n = 4000000)Rows Removed by Filter: 1250000Planning time: 0.119 msExecution time: 191.817 ms (8 rows)?
- 通過(guò)create table test(n int) with (parallel_workers = 4);強(qiáng)制啟動(dòng)4個(gè)worker進(jìn)程測(cè)試。
對(duì)比查詢結(jié)果:
| 1 worker 進(jìn)程 | 2 worker 進(jìn)程 | 3 worker 進(jìn)程 | 4 worker 進(jìn)程 |
| 302.026 ms | 219.005 ms | 191.817 ms | 185.391 ms |
可以看出,查詢效率并沒(méi)有隨worker數(shù)量線性增加;在啟用3個(gè)worker進(jìn)程 和 4個(gè)worker進(jìn)程進(jìn)行并行查詢時(shí),查詢效率基本一致了。所以并不是開(kāi)啟的worker數(shù)量越多,查詢效率越高,這個(gè)也是系統(tǒng)有成本考慮在內(nèi)。
?
?
轉(zhuǎn)載于:https://my.oschina.net/tianbing/blog/3029493
總結(jié)
以上是生活随笔為你收集整理的PostgreSQL 并行查询概述的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: testflight进行用户的beta测
- 下一篇: Node操作Mysql的简单例子