Mga parallel na query sa PostgreSQL

Mga parallel na query sa PostgreSQL
Ang mga modernong CPU ay may maraming mga core. Sa loob ng maraming taon, ang mga application ay nagpapadala ng mga query sa mga database nang magkatulad. Kung ito ay isang query ng ulat sa maraming row sa isang table, mas mabilis itong tatakbo kapag gumagamit ng maraming CPU, at nagawa na ito ng PostgreSQL mula noong bersyon 9.6.

Tumagal ng 3 taon upang ipatupad ang tampok na parallel na query - kinailangan naming muling isulat ang code sa iba't ibang yugto ng pagsasagawa ng query. Ipinakilala ng PostgreSQL 9.6 ang imprastraktura upang higit pang mapabuti ang code. Sa mga kasunod na bersyon, ang iba pang mga uri ng mga query ay isinasagawa nang magkatulad.

Paghihigpit

  • Huwag paganahin ang parallel execution kung ang lahat ng mga core ay abala na, kung hindi, ang ibang mga kahilingan ay bumagal.
  • Pinakamahalaga, ang parallel processing na may mataas na WORK_MEM values ​​​​ay gumagamit ng maraming memory - bawat hash join o sort ay tumatagal ng work_mem memory.
  • Ang mababang latency na mga query sa OLTP ay hindi maaaring pabilisin ng parallel execution. At kung ang query ay magbabalik ng isang hilera, ang parallel processing ay magpapabagal lamang nito.
  • Gustung-gusto ng mga developer na gamitin ang benchmark ng TPC-H. Marahil ay mayroon kang mga katulad na query para sa perpektong parallel na pagpapatupad.
  • Tanging ang mga SELECT query na walang pag-lock ng predicate ang pinapagana nang magkatulad.
  • Minsan ang tamang pag-index ay mas mahusay kaysa sa sequential table scan sa parallel mode.
  • Ang pag-pause ng mga query at cursor ay hindi suportado.
  • Ang mga function ng window at ang mga nakaayos na set aggregate function ay hindi magkatulad.
  • Wala kang makukuha sa I/O workload.
  • Walang mga parallel sorting algorithm. Ngunit ang mga query na may mga uri ay maaaring isagawa nang magkatulad sa ilang aspeto.
  • Palitan ang CTE (WITH ...) ng isang nested SELECT para paganahin ang parallel processing.
  • Hindi pa sinusuportahan ng mga third-party na data wrapper ang parallel processing (ngunit kaya nila!)
  • Ang FULL OUTER JOIN ay hindi suportado.
  • Hindi pinapagana ng max_rows ang parallel processing.
  • Kung ang isang query ay may function na hindi minarkahan ng PARALLEL SAFE, ito ay magiging single threaded.
  • Hindi pinapagana ng SERIALIZABLE na antas ng paghihiwalay ng transaksyon ang parallel processing.

Kapaligirang pang eksperiment

Sinubukan ng mga developer ng PostgreSQL na bawasan ang oras ng pagtugon ng mga benchmark na query sa TPC-H. I-download ang benchmark at iakma ito sa PostgreSQL. Ito ay isang hindi opisyal na paggamit ng TPC-H benchmark - hindi para sa database o paghahambing ng hardware.

  1. I-download ang TPC-H_Tools_v2.17.3.zip (o mas bagong bersyon) mula sa TPC offsite.
  2. Palitan ang pangalan ng makefile.suite sa Makefile at baguhin tulad ng inilarawan dito: https://github.com/tvondra/pg_tpch . I-compile ang code gamit ang make command.
  3. Bumuo ng data: ./dbgen -s 10 lumilikha ng 23 GB na database. Ito ay sapat na upang makita ang pagkakaiba sa pagganap ng parallel at non-parallel na mga query.
  4. I-convert ang mga file tbl в csv с for и sed.
  5. I-clone ang repositoryo pg_tpch at kopyahin ang mga file csv в pg_tpch/dss/data.
  6. Lumikha ng mga query gamit ang isang command qgen.
  7. Mag-load ng data sa database gamit ang command ./tpch.sh.

Parallel sequential scanning

Maaaring mas mabilis ito hindi dahil sa parallel reading, ngunit dahil ang data ay kumakalat sa maraming CPU core. Sa modernong mga operating system, ang mga file ng data ng PostgreSQL ay mahusay na naka-cache. Sa maagang pagbabasa, posibleng makakuha ng mas malaking bloke mula sa storage kaysa sa mga kahilingan ng PG daemon. Samakatuwid, ang pagganap ng query ay hindi limitado ng disk I/O. Gumagamit ito ng mga cycle ng CPU upang:

  • basahin ang mga hilera nang paisa-isa mula sa mga pahina ng talahanayan;
  • ihambing ang mga halaga at kundisyon ng string WHERE.

Magpatakbo tayo ng isang simpleng query select:

tpch=# explain analyze select l_quantity as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Seq Scan on lineitem (cost=0.00..1964772.00 rows=58856235 width=5) (actual time=0.014..16951.669 rows=58839715 loops=1)
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 1146337
Planning Time: 0.203 ms
Execution Time: 19035.100 ms

Ang sunud-sunod na pag-scan ay gumagawa ng masyadong maraming mga hilera nang walang pagsasama-sama, kaya ang query ay isinasagawa ng isang core ng CPU.

Kung magdadagdag ka SUM(), makikita mo na ang dalawang daloy ng trabaho ay makakatulong na mapabilis ang query:

explain analyze select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=1589702.14..1589702.15 rows=1 width=32) (actual time=8553.365..8553.365 rows=1 loops=1)
-> Gather (cost=1589701.91..1589702.12 rows=2 width=32) (actual time=8553.241..8555.067 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=1588701.91..1588701.92 rows=1 width=32) (actual time=8547.546..8547.546 rows=1 loops=3)
-> Parallel Seq Scan on lineitem (cost=0.00..1527393.33 rows=24523431 width=5) (actual time=0.038..5998.417 rows=19613238 loops=3)
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 382112
Planning Time: 0.241 ms
Execution Time: 8555.131 ms

Parallel na pagsasama-sama

Ang Parallel Seq Scan node ay gumagawa ng mga row para sa bahagyang pagsasama-sama. Ang "Partial Aggregate" node ay pinuputol ang mga linyang ito gamit SUM(). Sa dulo, ang SUM counter mula sa bawat proseso ng manggagawa ay kinokolekta ng "Gather" node.

Ang panghuling resulta ay kinakalkula ng "Finalize Aggregate" node. Kung mayroon kang sariling mga function ng pagsasama-sama, huwag kalimutang markahan ang mga ito bilang "parallel safe".

Bilang ng mga proseso ng manggagawa

Maaaring madagdagan ang bilang ng mga proseso ng manggagawa nang hindi na-restart ang server:

explain analyze select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day;
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=1589702.14..1589702.15 rows=1 width=32) (actual time=8553.365..8553.365 rows=1 loops=1)
-> Gather (cost=1589701.91..1589702.12 rows=2 width=32) (actual time=8553.241..8555.067 rows=3 loops=1)
Workers Planned: 2
Workers Launched: 2
-> Partial Aggregate (cost=1588701.91..1588701.92 rows=1 width=32) (actual time=8547.546..8547.546 rows=1 loops=3)
-> Parallel Seq Scan on lineitem (cost=0.00..1527393.33 rows=24523431 width=5) (actual time=0.038..5998.417 rows=19613238 loops=3)
Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)
Rows Removed by Filter: 382112
Planning Time: 0.241 ms
Execution Time: 8555.131 ms

Anong nangyayari dito? Mayroong 2 beses na mas maraming proseso sa trabaho, at ang kahilingan ay naging 1,6599 beses na mas mabilis. Ang mga kalkulasyon ay kawili-wili. Mayroon kaming 2 proseso ng manggagawa at 1 pinuno. Pagkatapos ng pagbabago ay naging 4+1 ito.

Ang aming maximum na bilis mula sa parallel processing: 5/3 = 1,66(6) beses.

Paano ito gumagana?

Ang mga proseso

Palaging nagsisimula ang pagpapatupad ng kahilingan sa nangungunang proseso. Ginagawa ng pinuno ang lahat ng hindi parallel at ilang parallel na pagproseso. Ang iba pang mga proseso na nagsasagawa ng parehong mga kahilingan ay tinatawag na mga proseso ng manggagawa. Ang parallel processing ay gumagamit ng imprastraktura pabago-bagong proseso ng manggagawa sa background (mula sa bersyon 9.4). Dahil ang ibang bahagi ng PostgreSQL ay gumagamit ng mga proseso sa halip na mga thread, ang isang query na may 3 proseso ng manggagawa ay maaaring 4 na beses na mas mabilis kaysa sa tradisyonal na pagproseso.

Pakipagtulungan

Ang mga proseso ng manggagawa ay nakikipag-usap sa pinuno sa pamamagitan ng isang pila ng mensahe (batay sa nakabahaging memorya). Ang bawat proseso ay may 2 queues: para sa mga error at para sa tuples.

Gaano karaming mga daloy ng trabaho ang kailangan?

Ang pinakamababang limitasyon ay tinukoy ng parameter max_parallel_workers_per_gather. Ang request runner ay kukuha ng mga proseso ng manggagawa mula sa pool na limitado ng parameter max_parallel_workers size. Ang huling limitasyon ay max_worker_processes, iyon ay, ang kabuuang bilang ng mga proseso sa background.

Kung hindi posible na maglaan ng proseso ng manggagawa, ang pagpoproseso ay magiging solong proseso.

Maaaring bawasan ng tagaplano ng query ang mga daloy ng trabaho depende sa laki ng talahanayan o index. Mayroong mga parameter para dito min_parallel_table_scan_size и min_parallel_index_scan_size.

set min_parallel_table_scan_size='8MB'
8MB table => 1 worker
24MB table => 2 workers
72MB table => 3 workers
x => log(x / min_parallel_table_scan_size) / log(3) + 1 worker

Sa bawat oras na ang talahanayan ay 3 beses na mas malaki kaysa sa min_parallel_(index|table)_scan_size, nagdagdag ang Postgres ng proseso ng manggagawa. Ang bilang ng mga daloy ng trabaho ay hindi batay sa mga gastos. Ang circular dependency ay nagpapahirap sa mga kumplikadong pagpapatupad. Sa halip, ang tagaplano ay gumagamit ng mga simpleng panuntunan.

Sa pagsasagawa, ang mga panuntunang ito ay hindi palaging angkop para sa produksyon, kaya maaari mong baguhin ang bilang ng mga proseso ng manggagawa para sa isang partikular na talahanayan: ALTER TABLE ... SET (parallel_workers = N).

Bakit hindi ginagamit ang parallel processing?

Bilang karagdagan sa mahabang listahan ng mga paghihigpit, mayroon ding mga pagsusuri sa gastos:

parallel_setup_cost - upang maiwasan ang magkatulad na pagproseso ng mga maikling kahilingan. Tinatantya ng parameter na ito ang oras upang ihanda ang memorya, simulan ang proseso, at paunang palitan ng data.

parallel_tuple_cost: Ang komunikasyon sa pagitan ng pinuno at mga manggagawa ay maaaring maantala sa proporsyon sa bilang ng mga tuple mula sa mga proseso ng trabaho. Kinakalkula ng parameter na ito ang halaga ng palitan ng data.

Nested Loop Joins

PostgreSQL 9.6+ может выполнять вложенные циклы параллельно — это простая операция.

explain (costs off) select c_custkey, count(o_orderkey)
                from    customer left outer join orders on
                                c_custkey = o_custkey and o_comment not like '%special%deposits%'
                group by c_custkey;
                                      QUERY PLAN
--------------------------------------------------------------------------------------
 Finalize GroupAggregate
   Group Key: customer.c_custkey
   ->  Gather Merge
         Workers Planned: 4
         ->  Partial GroupAggregate
               Group Key: customer.c_custkey
               ->  Nested Loop Left Join
                     ->  Parallel Index Only Scan using customer_pkey on customer
                     ->  Index Scan using idx_orders_custkey on orders
                           Index Cond: (customer.c_custkey = o_custkey)
                           Filter: ((o_comment)::text !~~ '%special%deposits%'::text)

Ang koleksyon ay nangyayari sa huling yugto, kaya ang Nested Loop Left Join ay isang parallel na operasyon. Ang Parallel Index Only Scan ay ipinakilala lamang sa bersyon 10. Ito ay gumagana katulad ng parallel serial scanning. Kundisyon c_custkey = o_custkey nagbabasa ng isang order sa bawat string ng kliyente. Kaya hindi ito parallel.

Sumali sa Hash

Ang bawat proseso ng manggagawa ay gumagawa ng sarili nitong hash table hanggang sa PostgreSQL 11. At kung mayroong higit sa apat sa mga prosesong ito, hindi gaganda ang performance. Sa bagong bersyon, ibinahagi ang hash table. Ang bawat proseso ng manggagawa ay maaaring gumamit ng WORK_MEM para gumawa ng hash table.

select
        l_shipmode,
        sum(case
                when o_orderpriority = '1-URGENT'
                        or o_orderpriority = '2-HIGH'
                        then 1
                else 0
        end) as high_line_count,
        sum(case
                when o_orderpriority <> '1-URGENT'
                        and o_orderpriority <> '2-HIGH'
                        then 1
                else 0
        end) as low_line_count
from
        orders,
        lineitem
where
        o_orderkey = l_orderkey
        and l_shipmode in ('MAIL', 'AIR')
        and l_commitdate < l_receiptdate
        and l_shipdate < l_commitdate
        and l_receiptdate >= date '1996-01-01'
        and l_receiptdate < date '1996-01-01' + interval '1' year
group by
        l_shipmode
order by
        l_shipmode
LIMIT 1;
                                                                                                                                    QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=1964755.66..1964961.44 rows=1 width=27) (actual time=7579.592..7922.997 rows=1 loops=1)
   ->  Finalize GroupAggregate  (cost=1964755.66..1966196.11 rows=7 width=27) (actual time=7579.590..7579.591 rows=1 loops=1)
         Group Key: lineitem.l_shipmode
         ->  Gather Merge  (cost=1964755.66..1966195.83 rows=28 width=27) (actual time=7559.593..7922.319 rows=6 loops=1)
               Workers Planned: 4
               Workers Launched: 4
               ->  Partial GroupAggregate  (cost=1963755.61..1965192.44 rows=7 width=27) (actual time=7548.103..7564.592 rows=2 loops=5)
                     Group Key: lineitem.l_shipmode
                     ->  Sort  (cost=1963755.61..1963935.20 rows=71838 width=27) (actual time=7530.280..7539.688 rows=62519 loops=5)
                           Sort Key: lineitem.l_shipmode
                           Sort Method: external merge  Disk: 2304kB
                           Worker 0:  Sort Method: external merge  Disk: 2064kB
                           Worker 1:  Sort Method: external merge  Disk: 2384kB
                           Worker 2:  Sort Method: external merge  Disk: 2264kB
                           Worker 3:  Sort Method: external merge  Disk: 2336kB
                           ->  Parallel Hash Join  (cost=382571.01..1957960.99 rows=71838 width=27) (actual time=7036.917..7499.692 rows=62519 loops=5)
                                 Hash Cond: (lineitem.l_orderkey = orders.o_orderkey)
                                 ->  Parallel Seq Scan on lineitem  (cost=0.00..1552386.40 rows=71838 width=19) (actual time=0.583..4901.063 rows=62519 loops=5)
                                       Filter: ((l_shipmode = ANY ('{MAIL,AIR}'::bpchar[])) AND (l_commitdate < l_receiptdate) AND (l_shipdate < l_commitdate) AND (l_receiptdate >= '1996-01-01'::date) AND (l_receiptdate < '1997-01-01 00:00:00'::timestamp without time zone))
                                       Rows Removed by Filter: 11934691
                                 ->  Parallel Hash  (cost=313722.45..313722.45 rows=3750045 width=20) (actual time=2011.518..2011.518 rows=3000000 loops=5)
                                       Buckets: 65536  Batches: 256  Memory Usage: 3840kB
                                       ->  Parallel Seq Scan on orders  (cost=0.00..313722.45 rows=3750045 width=20) (actual time=0.029..995.948 rows=3000000 loops=5)
 Planning Time: 0.977 ms
 Execution Time: 7923.770 ms

Ang Query 12 mula sa TPC-H ay malinaw na nagpapakita ng parallel hash connection. Ang bawat proseso ng manggagawa ay nag-aambag sa paglikha ng isang karaniwang hash table.

Pagsamahin ang Sumali

Ang isang merge join ay hindi parallel sa kalikasan. Huwag mag-alala kung ito na ang huling hakbang ng query - maaari pa rin itong tumakbo nang magkatulad.

-- Query 2 from TPC-H
explain (costs off) select s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment
from    part, supplier, partsupp, nation, region
where
        p_partkey = ps_partkey
        and s_suppkey = ps_suppkey
        and p_size = 36
        and p_type like '%BRASS'
        and s_nationkey = n_nationkey
        and n_regionkey = r_regionkey
        and r_name = 'AMERICA'
        and ps_supplycost = (
                select
                        min(ps_supplycost)
                from    partsupp, supplier, nation, region
                where
                        p_partkey = ps_partkey
                        and s_suppkey = ps_suppkey
                        and s_nationkey = n_nationkey
                        and n_regionkey = r_regionkey
                        and r_name = 'AMERICA'
        )
order by s_acctbal desc, n_name, s_name, p_partkey
LIMIT 100;
                                                QUERY PLAN
----------------------------------------------------------------------------------------------------------
 Limit
   ->  Sort
         Sort Key: supplier.s_acctbal DESC, nation.n_name, supplier.s_name, part.p_partkey
         ->  Merge Join
               Merge Cond: (part.p_partkey = partsupp.ps_partkey)
               Join Filter: (partsupp.ps_supplycost = (SubPlan 1))
               ->  Gather Merge
                     Workers Planned: 4
                     ->  Parallel Index Scan using <strong>part_pkey</strong> on part
                           Filter: (((p_type)::text ~~ '%BRASS'::text) AND (p_size = 36))
               ->  Materialize
                     ->  Sort
                           Sort Key: partsupp.ps_partkey
                           ->  Nested Loop
                                 ->  Nested Loop
                                       Join Filter: (nation.n_regionkey = region.r_regionkey)
                                       ->  Seq Scan on region
                                             Filter: (r_name = 'AMERICA'::bpchar)
                                       ->  Hash Join
                                             Hash Cond: (supplier.s_nationkey = nation.n_nationkey)
                                             ->  Seq Scan on supplier
                                             ->  Hash
                                                   ->  Seq Scan on nation
                                 ->  Index Scan using idx_partsupp_suppkey on partsupp
                                       Index Cond: (ps_suppkey = supplier.s_suppkey)
               SubPlan 1
                 ->  Aggregate
                       ->  Nested Loop
                             Join Filter: (nation_1.n_regionkey = region_1.r_regionkey)
                             ->  Seq Scan on region region_1
                                   Filter: (r_name = 'AMERICA'::bpchar)
                             ->  Nested Loop
                                   ->  Nested Loop
                                         ->  Index Scan using idx_partsupp_partkey on partsupp partsupp_1
                                               Index Cond: (part.p_partkey = ps_partkey)
                                         ->  Index Scan using supplier_pkey on supplier supplier_1
                                               Index Cond: (s_suppkey = partsupp_1.ps_suppkey)
                                   ->  Index Scan using nation_pkey on nation nation_1
                                         Index Cond: (n_nationkey = supplier_1.s_nationkey)

Ang "Merge Join" node ay matatagpuan sa itaas ng "Gather Merge". Kaya ang pagsasama ay hindi gumagamit ng parallel processing. Ngunit nakakatulong pa rin ang "Parallel Index Scan" na node sa segment part_pkey.

Koneksyon ayon sa mga seksyon

Sa PostgreSQL 11 koneksyon ayon sa mga seksyon hindi pinagana bilang default: mayroon itong napakamahal na pag-iiskedyul. Ang mga talahanayan na may katulad na pagkahati ay maaaring pagsamahin ang pagkahati sa pamamagitan ng pagkahati. Sa ganitong paraan gagamit ang Postgres ng mas maliliit na hash table. Ang bawat koneksyon ng mga seksyon ay maaaring magkatulad.

tpch=# set enable_partitionwise_join=t;
tpch=# explain (costs off) select * from prt1 t1, prt2 t2
where t1.a = t2.b and t1.b = 0 and t2.b between 0 and 10000;
                    QUERY PLAN
---------------------------------------------------
 Append
   ->  Hash Join
         Hash Cond: (t2.b = t1.a)
         ->  Seq Scan on prt2_p1 t2
               Filter: ((b >= 0) AND (b <= 10000))
         ->  Hash
               ->  Seq Scan on prt1_p1 t1
                     Filter: (b = 0)
   ->  Hash Join
         Hash Cond: (t2_1.b = t1_1.a)
         ->  Seq Scan on prt2_p2 t2_1
               Filter: ((b >= 0) AND (b <= 10000))
         ->  Hash
               ->  Seq Scan on prt1_p2 t1_1
                     Filter: (b = 0)
tpch=# set parallel_setup_cost = 1;
tpch=# set parallel_tuple_cost = 0.01;
tpch=# explain (costs off) select * from prt1 t1, prt2 t2
where t1.a = t2.b and t1.b = 0 and t2.b between 0 and 10000;
                        QUERY PLAN
-----------------------------------------------------------
 Gather
   Workers Planned: 4
   ->  Parallel Append
         ->  Parallel Hash Join
               Hash Cond: (t2_1.b = t1_1.a)
               ->  Parallel Seq Scan on prt2_p2 t2_1
                     Filter: ((b >= 0) AND (b <= 10000))
               ->  Parallel Hash
                     ->  Parallel Seq Scan on prt1_p2 t1_1
                           Filter: (b = 0)
         ->  Parallel Hash Join
               Hash Cond: (t2.b = t1.a)
               ->  Parallel Seq Scan on prt2_p1 t2
                     Filter: ((b >= 0) AND (b <= 10000))
               ->  Parallel Hash
                     ->  Parallel Seq Scan on prt1_p1 t1
                           Filter: (b = 0)

Ang pangunahing bagay ay ang koneksyon sa mga seksyon ay parallel lamang kung ang mga seksyong ito ay sapat na malaki.

Parallel Append

Parallel Append ay maaaring gamitin sa halip ng iba't ibang mga bloke sa iba't ibang mga daloy ng trabaho. Karaniwan itong nangyayari sa mga query ng UNION ALL. Ang kawalan ay hindi gaanong paralelismo, dahil ang bawat proseso ng manggagawa ay nagpoproseso lamang ng 1 kahilingan.

Mayroong 2 proseso ng manggagawa na tumatakbo dito, bagama't 4 ang pinagana.

tpch=# explain (costs off) select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '1998-12-01' - interval '105' day union all select sum(l_quantity) as sum_qty from lineitem where l_shipdate <= date '2000-12-01' - interval '105' day;
                                           QUERY PLAN
------------------------------------------------------------------------------------------------
 Gather
   Workers Planned: 2
   ->  Parallel Append
         ->  Aggregate
               ->  Seq Scan on lineitem
                     Filter: (l_shipdate <= '2000-08-18 00:00:00'::timestamp without time zone)
         ->  Aggregate
               ->  Seq Scan on lineitem lineitem_1
                     Filter: (l_shipdate <= '1998-08-18 00:00:00'::timestamp without time zone)

Ang pinakamahalagang mga variable

  • Nililimitahan ng WORK_MEM ang memorya sa bawat proseso, hindi lang mga query: work_mem proseso mga koneksyon = maraming memorya.
  • max_parallel_workers_per_gather — kung gaano karaming manggagawa ang magpoproseso ng executing program na gagamitin para sa parallel processing mula sa plano.
  • max_worker_processes — inaayos ang kabuuang bilang ng mga proseso ng manggagawa sa bilang ng mga core ng CPU sa server.
  • max_parallel_workers - pareho, ngunit para sa mga parallel na proseso ng trabaho.

Mga resulta ng

Mula sa bersyon 9.6, ang parallel processing ay maaaring lubos na mapabuti ang pagganap ng mga kumplikadong query na nag-scan ng maraming row o index. Sa PostgreSQL 10, ang parallel processing ay pinagana bilang default. Tandaan na huwag paganahin ito sa mga server na may malaking OLTP workload. Ang mga sunud-sunod na pag-scan o index scan ay gumagamit ng maraming mapagkukunan. Kung hindi ka nagpapatakbo ng isang ulat sa buong dataset, maaari mong pagbutihin ang pagganap ng query sa pamamagitan lamang ng pagdaragdag ng mga nawawalang index o paggamit ng wastong paghati.

sanggunian

Pinagmulan: www.habr.com

Magdagdag ng komento