{"id":30900,"date":"2019-10-31T21:38:02","date_gmt":"2019-10-31T18:38:02","guid":{"rendered":"https:\/\/prohoster.info\/blog\/parallelnye-zaprosy-v-postgresql\/"},"modified":"2019-10-31T21:38:02","modified_gmt":"2019-10-31T18:38:02","slug":"parallelnye-zaprosy-v-postgresql","status":"publish","type":"post","link":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/parallelnye-zaprosy-v-postgresql","title":{"rendered":"Paral\u0113lie vaic\u0101jumi PostgreSQL","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Paral\u0113lie vaic\u0101jumi PostgreSQL\" src=\"\/wp-content\/uploads\/2019\/04\/bbb4b4d3f8714bbdb9b26ada2f2253b5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nM\u016bsdienu CPU ir \u013coti daudz kodolu. Gadiem ilgi programmas nos\u016bt\u012bja piepras\u012bjumus datu b\u0101z\u0113m paral\u0113li. Ja tas ir zi\u0146ojumu piepras\u012bjums uz daudz\u0101m tabulas rind\u0101m, tas tiek izpild\u012bts \u0101tr\u0101k, kad tiek izmantoti vair\u0101ki CPU, un PostgreSQL to atbalsta kop\u0161 9.6 versijas.<\/p>\n<p><\/p>\n<p>Bija nepiecie\u0161ami tr\u012bs gadi, lai \u012bstenotu paral\u0113lo piepras\u012bjumu funkcionalit\u0101ti \u2014 bija j\u0101p\u0101rstr\u0101d\u0101 kods da\u017e\u0101dos piepras\u012bjumu izpildes posmos. PostgreSQL 9.6 ieviesa infrastrukt\u016bru koda t\u0101l\u0101kai uzlabo\u0161anai. N\u0101kamaj\u0101s versij\u0101s ar\u012b citi piepras\u012bjumu veidi tiek izpild\u012bti paral\u0113li.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3 id=\"ogranicheniya\">ierobe\u017eojumi<\/h3>\n<p><\/p>\n<ul>\n<li>Neiesl\u0113dziet paral\u0113lo izpildi, ja visi kodoli jau ir noslogoti, cit\u0101di citi piepras\u012bjumi tiks kav\u0113ti.<\/li>\n<li>Galvenais, ka paral\u0113l\u0101 apstr\u0101de ar augst\u0101m WORK_MEM v\u0113rt\u012bb\u0101m izmanto daudz atmi\u0146as \u2014 katrs hash savienojums vai k\u0101rto\u0161ana aiz\u0146em atmi\u0146u tilpum\u0101, kas noteikts work_mem.<\/li>\n<li>OLTP piepras\u012bjumus ar zemu latentumu nav iesp\u0113jams pa\u0101trin\u0101t, izmantojot paral\u0113lo izpildi. Ja piepras\u012bjums atgrie\u017e vienu rindu, paral\u0113l\u0101 apstr\u0101de to tikai pal\u0113nin\u0101s.<\/li>\n<li>Izstr\u0101d\u0101t\u0101jiem pat\u012bk izmantot TPC-H veiktsp\u0113jas testu. Varb\u016bt jums ir l\u012bdz\u012bgi piepras\u012bjumi ide\u0101lai paral\u0113l\u0101 izpildei.<\/li>\n<li>Tikai SELECT piepras\u012bjumi bez predik\u0101ta blo\u0137\u0113\u0161anas tiek izpild\u012bti paral\u0113li.<\/li>\n<li>Da\u017ek\u0101rt pareiza indeks\u0101cija b\u016bs lab\u0101ka par sec\u012bgu tabulas sken\u0113\u0161anu paral\u0113laj\u0101 re\u017e\u012bm\u0101.<\/li>\n<li>Pieteikumu aptur\u0113\u0161ana un kursoru atbalsts netiek nodro\u0161in\u0101ts.<\/li>\n<li>Logu funkcijas un k\u0101rto\u0161anas funkcij\u0101m nav paral\u0113l\u0101s apstr\u0101des.<\/li>\n<li>J\u016bs neg\u016bstat nek\u0101du labumu no ievades-izvades darba slodzes.<\/li>\n<li>Nav paral\u0113lo k\u0101rto\u0161anas algoritmu. Bet piepras\u012bjumi ar k\u0101rto\u0161anu var tikt izpild\u012bti paral\u0113li noteiktos aspektos.<\/li>\n<li>Aizvietojiet CTE (WITH \u2026) ar iegulto SELECT, lai iek\u013cautu paral\u0113lo apstr\u0101di.<\/li>\n<li>Tre\u0161o pu\u0161u datu apvalki pa\u0161laik neatbalsta paral\u0113lo apstr\u0101di (bet var\u0113tu!).<\/li>\n<li>FULL OUTER JOIN netiek atbalst\u012bts.<\/li>\n<li>max_rows atsp\u0113jo paral\u0113lo apstr\u0101di.<\/li>\n<li>Ja piepras\u012bjum\u0101 ir funkcija, kas nav atz\u012bta par PARALLEL SAFE, tas darbosies vien\u0101 pavedien\u0101.<\/li>\n<li>TRANSACTION SERIALIZABLE izol\u0101cijas l\u012bmenis atsp\u0113jo paral\u0113lo apstr\u0101di.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"testovaya-sreda\">Test\u0113\u0161anas vide<\/h3>\n<p><\/p>\n<p>PostgreSQL izstr\u0101d\u0101t\u0101ji cent\u0101s samazin\u0101t TPC-H veiktsp\u0113jas testu piepras\u012bjumu atbildes laiku. Lejupiel\u0101d\u0113jiet veiktsp\u0113jas testu un <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/tvondra\/pg_tpch\">piel\u0101gojiet to PostgreSQL<\/a><\/noindex>. Tas ir neofici\u0101ls TPC-H veiktsp\u0113jas testa izmantojums \u2014 nav paredz\u0113ts datu b\u0101zu vai apr\u012bkojuma sal\u012bdzin\u0101\u0161anai.<\/p>\n<p><\/p>\n<ol>\n<li>Lejupiel\u0101d\u0113jiet TPC-H_Tools_v2.17.3.zip (vai jaun\u0101ku versiju) <noindex><a rel=\"nofollow\" href=\"http:\/\/www.tpc.org\/tpc_documents_current_versions\/current_specifications.asp\">no TPC ofici\u0101l\u0101s vietnes<\/a><\/noindex>.<\/li>\n<li>P\u0101rsaukt makefile.suite par Makefile un mainiet, k\u0101 aprakst\u012bts \u0161eit: <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/tvondra\/pg_tpch\">https:\/\/github.com\/tvondra\/pg_tpch <\/a><\/noindex>. Sast\u0101diet kodu ar komandu make.<\/li>\n<li>Izveidojiet datus: <code>.\/dbgen -s 10<\/code> izveido datub\u0101zi ar 23 GB. \u0160is apjoms ir pietiekams, lai redz\u0113tu veiktsp\u0113jas at\u0161\u0137ir\u012bbu starp paral\u0113lajiem un nep\u0101rtraukto vaic\u0101jumiem.<\/li>\n<li>P\u0101rveidojiet failus <code>tbl<\/code> par <code>csv ar for<\/code> un <code>sed<\/code>.<\/li>\n<li>Klon\u0113jiet repozitoriju <code>pg_tpch<\/code> un kop\u0113jiet failus <code>csv<\/code> par <code>pg_tpch\/dss\/data<\/code>.<\/li>\n<li>Izveidojiet vaic\u0101jumus ar komandu <code>qgen<\/code>.<\/li>\n<li>Iel\u0101d\u0113jiet datus datub\u0101z\u0113 ar komandu <code>.\/tpch.sh<\/code>.<\/li>\n<\/ol>\n<p><\/p>\n<h3 id=\"parallelnoe-posledovatelnoe-skanirovanie\">Paral\u0113la sec\u012bga sken\u0113\u0161ana<\/h3>\n<p><\/p>\n<p>T\u0101 var b\u016bt \u0101tr\u0101ka nevis paral\u0113l\u0101s las\u012b\u0161anas d\u0113\u013c, bet gan t\u0101p\u0113c, ka dati ir izklied\u0113ti pa daudz\u0101m CPU kodol\u0101m. M\u016bsdienu oper\u0113t\u0101jsist\u0113m\u0101s PostgreSQL datu faili ir labi ke\u0161oti. Ar iepriek\u0161\u0113ju las\u012b\u0161anu var ieg\u016bt vair\u0101k blokus no kr\u0101tuves, nek\u0101 pieprasa PG demons. T\u0101d\u0113j\u0101di vaic\u0101juma veiktsp\u0113ja nav ierobe\u017eota ar diska ievadi-izvadi. Tas pat\u0113r\u0113 CPU ciklus, lai:<\/p>\n<p><\/p>\n<ul>\n<li>las\u012btu rindas pa vienai no tabulas lap\u0101m;<\/li>\n<li>sal\u012bdzin\u0101tu rindas v\u0113rt\u012bbas un nosac\u012bjumus <code>WHERE<\/code>.<\/li>\n<\/ul>\n<p><\/p>\n<p>Izpild\u012bsim vienk\u0101r\u0161u vaic\u0101jumu <code>select<\/code>:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">tpch=# explain analyze select l_quantity as sum_qty from lineitem where l_shipdate &lt;= date &#039;1998-12-01&#039; - interval &#039;105&#039; day;\nQUERY PLAN\n--------------------------------------------------------------------------------------------------------------------------\nSeq Scan on lineitem (cost=0.00..1964772.00 rows=58856235 width=5) (actual time=0.014..16951.669 rows=58839715 loops=1)\nFilter: (l_shipdate &lt;= &#039;1998-08-18 00:00:00&#039;::timestamp without time zone)\nRows Removed by Filter: 1146337\nPlanning Time: 0.203 ms\nExecution Time: 19035.100 ms<\/code><\/pre>\n<p><\/p>\n<p>Sec\u012bga sken\u0113\u0161ana dod p\u0101r\u0101k daudz rindu bez agreg\u0101cijas, t\u0101d\u0113\u013c vaic\u0101jumu izpilda viens CPU kodols.<\/p>\n<p><\/p>\n<p>Ja pievienojam <code>SUM()<\/code>, tad redzam, ka divi darba procesi pal\u012bdz\u0113s pa\u0101trin\u0101t vaic\u0101jumu:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">explain analyze select sum(l_quantity) as sum_qty from lineitem where l_shipdate  Gather (cost=1589701.91..1589702.12 rows=2 width=32) (actual time=8553.241..8555.067 rows=3 loops=1)\nWorkers Planned: 2\nWorkers Launched: 2\n-&gt; Partial Aggregate (cost=1588701.91..1588701.92 rows=1 width=32) (actual time=8547.546..8547.546 rows=1 loops=3)\n-&gt; Parallel Seq Scan on lineitem (cost=0.00..1527393.33 rows=24523431 width=5) (actual time=0.038..5998.417 rows=19613238 loops=3)\nFilter: (l_shipdate &lt;= &#039;1998-08-18 00:00:00&#039;::timestamp without time zone)\nRows Removed by Filter: 382112\nPlanning Time: 0.241 ms\nExecution Time: 8555.131 ms<\/code><\/pre>\n<p><\/p>\n<h3 id=\"parallelnaya-agregaciya\">Paral\u0113l\u0101 agreg\u0101cija<\/h3>\n<p><\/p>\n<p>Noda &#171;Parallel Seq Scan&#187; \u0123ener\u0113 rindas da\u013c\u0113jai agreg\u0101cijai. Noda &#171;Partial Aggregate&#187; sa\u0161aurina \u0161\u012bs rindas, izmantojot <code>SUM()<\/code>. Beig\u0101s SUM skait\u012bt\u0101js no katra darba procesa tiek apkopots ar noda &#171;Gather&#187;.<\/p>\n<p><\/p>\n<p>Gal\u012bgais rezult\u0101ts tiek apr\u0113\u0137in\u0101ts ar noda &#171;Finalize Aggregate&#187;. Ja jums ir savas agreg\u0101cijas funkcijas, neaizmirstiet t\u0101s mar\u0137\u0113t k\u0101 &#171;parallel safe&#187;.<\/p>\n<p><\/p>\n<h3 id=\"kolichestvo-rabochih-processov\">Darba procesu skaits<\/h3>\n<p><\/p>\n<p>Darba procesu skaitu var palielin\u0101t bez servera restart\u0113\u0161anas:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">explain analyze select sum(l_quantity) as sum_qty from lineitem where l_shipdate  Gather (cost=1589701.91..1589702.12 rows=2 width=32) (actual time=8553.241..8555.067 rows=3 loops=1)\nWorkers Planned: 2\nWorkers Launched: 2\n-&gt; Partial Aggregate (cost=1588701.91..1588701.92 rows=1 width=32) (actual time=8547.546..8547.546 rows=1 loops=3)\n-&gt; Parallel Seq Scan on lineitem (cost=0.00..1527393.33 rows=24523431 width=5) (actual time=0.038..5998.417 rows=19613238 loops=3)\nFilter: (l_shipdate &lt;= &#039;1998-08-18 00:00:00&#039;::timestamp without time zone)\nRows Removed by Filter: 382112\nPlanning Time: 0.241 ms\nExecution Time: 8555.131 ms<\/code><\/pre>\n<p><\/p>\n<p>Kas \u0161eit notiek? Darba procesu skaits ir divreiz liel\u0101ks, bet piepras\u012bjums ir k\u013cuvis tikai 1,6599 reizes \u0101tr\u0101ks. Apr\u0113\u0137ini ir interesanti. Mums bija 2 darba procesi un 1 l\u012bderis. P\u0113c izmai\u0146\u0101m ir 4+1.<\/p>\n<p><\/p>\n<p>M\u016bsu maksim\u0101lais pa\u0101trin\u0101jums no paral\u0113las apstr\u0101des: 5\/3 = 1,66(6) reizes.<\/p>\n<p><\/p>\n<h2 id=\"kak-eto-rabotaet\">K\u0101 tas darbojas?<\/h2>\n<p><\/p>\n<h3 id=\"processy\">Procesi<\/h3>\n<p><\/p>\n<p>Piepras\u012bjuma izpilde vienm\u0113r s\u0101kas ar l\u012bderi. L\u012bderis veic visus nep\u0101rveidotos un da\u013cu paral\u0113l\u0101s apstr\u0101des. Citus procesus, kas veic tos pa\u0161us piepras\u012bjumus, sauc par darba procesiem. Paral\u0113l\u0101 apstr\u0101de izmanto infrastrukt\u016bru <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/bgworker.html\">dinamiskajiem fona darba procesiem<\/a><\/noindex> (s\u0101kot ar versiju 9.4). T\u0101 k\u0101 citas PostgreSQL da\u013cas izmanto procesus, nevis pavedienus, piepras\u012bjums ar 3 darba procesiem var\u0113ja b\u016bt 4 reizes \u0101tr\u0101ks nek\u0101 tradicion\u0101l\u0101 apstr\u0101de.<\/p>\n<p><\/p>\n<h3 id=\"vzaimodeystvie\">Sadarb\u012bba<\/h3>\n<p><\/p>\n<p>Darba procesi sazin\u0101s ar l\u012bderi caur zi\u0146ojumu rindu (balst\u012btu uz kop\u0113ju atmi\u0146u). Katram procesam ir 2 rindas: k\u013c\u016bdu un krop\u013cojumu.<\/p>\n<p><\/p>\n<h3 id=\"skolko-nuzhno-rabochih-processov\">Cik daudz darba procesu ir nepiecie\u0161ams?<\/h3>\n<p><\/p>\n<p>Minim\u0101l\u0101s robe\u017eas nosaka parametrs <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER\"><code>max_parallel_workers_per_gather<\/code><\/a><\/noindex>. P\u0113c tam piepras\u012bjumu izpild\u012bt\u0101js \u0146em darba procesus no rijuma, ko ierobe\u017eo parametrs <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES\"><code>max_parallel_workers size<\/code><\/a><\/noindex>. P\u0113d\u0113j\u0101 robe\u017ea ir <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES\"><code>max_worker_processes<\/code><\/a><\/noindex>, tas ir, kop\u0113jais fona procesu skaits.<\/p>\n<p><\/p>\n<p>Ja neizdodas pie\u0161\u0137irt darba procesu, apstr\u0101de b\u016bs vienprocesa.<\/p>\n<p><\/p>\n<p>Piepras\u012bjumu pl\u0101not\u0101js var samazin\u0101t darba procesus atkar\u012bb\u0101 no tabulas vai indeksa lieluma. Tam ir parametri <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-query.html#GUC-MIN-PARALLEL-TABLE-SCAN-SIZE\"><code>min_parallel_table_scan_size<\/code><\/a><\/noindex> un <noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-query.html#GUC-MIN-PARALLEL-INDEX-SCAN-SIZE\"><code>min_parallel_index_scan_size<\/code><\/a><\/noindex>.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">set min_parallel_table_scan_size='8MB'\n8MB tabula =&gt; 1 darbinieks\n24MB tabula =&gt; 2 darbinieki\n72MB tabula =&gt; 3 darbinieki\nx =&gt; log(x \/ min_parallel_table_scan_size) \/ log(3) + 1 darbinieks<\/code><\/pre>\n<p><\/p>\n<p>Ikreiz, kad tabula ir 3 reizes liel\u0101ka nek\u0101 <code>min_parallel_(index|table)_scan_size<\/code>, Postgres pievieno darba procesu. Darba procesu skaits nav balst\u012bts uz izmaks\u0101m. Cirkul\u0101r\u0101 atkar\u012bba apgr\u016btina sare\u017e\u0123\u012btu realiz\u0101ciju. Viet\u0101 pl\u0101not\u0101js izmanto vienk\u0101r\u0161as normas.<\/p>\n<p><\/p>\n<p>Praks\u0113 \u0161\u012bs normas ne vienm\u0113r der ra\u017eo\u0161anai, t\u0101p\u0113c var main\u012bt darba procesu skaitu konkr\u0113tai tabulai: ALTER TABLE \u2026 SET (<code>parallel_workers = N<\/code>).<\/p>\n<p><\/p>\n<h3 id=\"pochemu-parallelnaya-obrabotka-ne-ispolzuetsya\">K\u0101p\u0113c paral\u0113l\u0101 apstr\u0101de netiek izmantota?<\/h3>\n<p><\/p>\n<p>Papildus garajam ierobe\u017eojumu sarakstam ir ar\u012b izmaksu p\u0101rbaudes:<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-query.html#GUC-PARALLEL-SETUP-COST\"><code>parallel_setup_cost<\/code><\/a><\/noindex> \u2014 lai izvair\u012btos no paral\u0113las apstr\u0101des \u012bsiem piepras\u012bjumiem. \u0160is parametrs apl\u0113\u0161 laiku, kas nepiecie\u0161ams atmi\u0146as sagatavo\u0161anai, procesa palai\u0161anai un s\u0101kotn\u0113jai datu apmai\u0146ai.<\/p>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/current\/runtime-config-query.html#GUC-PARALLEL-TUPLE-COST\"><code>parallel_tuple_cost<\/code><\/a><\/noindex>: sazi\u0146a starp vad\u012bt\u0101ju un darbiniekiem var ilgt proporcion\u0101li tuple skaitam darba procesiem. \u0160is parametrs apr\u0113\u0137ina apmai\u0146as izmaksas.<\/p>\n<p><\/p>\n<h3 id=\"soedineniya-vlozhennyh-ciklov--nested-loop-join\">Iek\u013cauto ciklu savienojumi \u2014 Nested Loop Join<\/h3>\n<p><\/p>\n<pre><code class=\"plaintext\">PostgreSQL 9.6+ var izpild\u012bt iegrav\u0113tus ciklus paral\u0113li \u2014 t\u0101 ir vienk\u0101r\u0161a oper\u0101cija.\n\nexplain (costs off) select c_custkey, count(o_orderkey)\n from customer left outer join orders on\n c_custkey = o_custkey and o_comment not like '%specialposits%'\n group by c_custkey;\n QUERY PLAN\n--------------------------------------------------------------------------------------\n Finalize GroupAggregate\n Group Key: customer.c_custkey\n -&gt; Gather Merge\n Workers Planned: 4\n -&gt; Partial GroupAggregate\n Group Key: customer.c_custkey\n -&gt; Nested Loop Left Join\n -&gt; Parallel Index Only Scan using customer_pkey on customer\n -&gt; Index Scan using idx_orders_custkey on orders\n Index Cond: (customer.c_custkey = o_custkey)\n Filter: ((o_comment)::text !~~ '%specialposits%'::text)<\/code><\/pre>\n<p><\/p>\n<p>Sav\u0101k\u0161ana notiek p\u0113d\u0113j\u0101 posm\u0101, t\u0101p\u0113c Nested Loop Left Join \u2014 t\u0101 ir paral\u0113la oper\u0101cija. Parallel Index Only Scan par\u0101d\u012bj\u0101s tikai versij\u0101 10. Tas darbojas l\u012bdz\u012bgi paral\u0113lajai sec\u012bgajai sken\u0113\u0161anai. Nosac\u012bjums <code>c_custkey = o_custkey<\/code> nolasa vienu pas\u016bt\u012bjumu katrai klienta rindai. T\u0101p\u0113c tas nav paral\u0113ls.<\/p>\n<p><\/p>\n<h3 id=\"hesh-soedinenie--hash-join\">Hash savienojums \u2014 Hash Join<\/h3>\n<p><\/p>\n<p>Katrs darba procesus izveido savu hash tabulu l\u012bdz PostgreSQL 11. Un, ja \u0161o procesu ir vair\u0101k nek\u0101 \u010detri, veiktsp\u0113ja neuzlabosies. Jaunaj\u0101 versij\u0101 hash tabula ir kop\u012bga. Katrs darba process var izmantot WORK_MEM, lai izveidotu hash tabulu.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">select\n        l_shipmode,\n        sum(case\n                when o_orderpriority = '1-URGENT'\n                        or o_orderpriority = '2-HIGH'\n                        then 1\n                else 0\n        end) as high_line_count,\n        sum(case\n                when o_orderpriority  '1-URGENT'\n                        and o_orderpriority  '2-HIGH'\n                        then 1\n                else 0\n        end) as low_line_count\nfrom\n        orders,\n        lineitem\nwhere\n        o_orderkey = l_orderkey\n        and l_shipmode in ('MAIL', 'AIR')\n        and l_commitdate &lt; l_receiptdate\n        and l_shipdate = date '1996-01-01'\n        and l_receiptdate   Finalize GroupAggregate  (cost=1964755.66..1966196.11 rows=7 width=27) (actual time=7579.590..7579.591 rows=1 loops=1)\n         Group Key: lineitem.l_shipmode\n         -&gt;  Gather Merge  (cost=1964755.66..1966195.83 rows=28 width=27) (actual time=7559.593..7922.319 rows=6 loops=1)\n               Workers Planned: 4\n               Workers Launched: 4\n               -&gt;  Partial GroupAggregate  (cost=1963755.61..1965192.44 rows=7 width=27) (actual time=7548.103..7564.592 rows=2 loops=5)\n                     Group Key: lineitem.l_shipmode\n                     -&gt;  Sort  (cost=1963755.61..1963935.20 rows=71838 width=27) (actual time=7530.280..7539.688 rows=62519 loops=5)\n                           Sort Key: lineitem.l_shipmode\n                           Sort Method: external merge  Disk: 2304kB\n                           Worker 0:  Sort Method: external merge  Disk: 2064kB\n                           Worker 1:  Sort Method: external merge  Disk: 2384kB\n                           Worker 2:  Sort Method: external merge  Disk: 2264kB\n                           Worker 3:  Sort Method: external merge  Disk: 2336kB\n                           -&gt;  Parallel Hash Join  (cost=382571.01..1957960.99 rows=71838 width=27) (actual time=7036.917..7499.692 rows=62519 loops=5)\n                                 Hash Cond: (lineitem.l_orderkey = orders.o_orderkey)\n                                 -&gt;  Parallel Seq Scan on lineitem  (cost=0.00..1552386.40 rows=71838 width=19) (actual time=0.583..4901.063 rows=62519 loops=5)\n                                       Filter: ((l_shipmode = ANY ('{MAIL,AIR}'::bpchar[])) AND (l_commitdate &lt; l_receiptdate) AND (l_shipdate = '1996-01-01'::date) AND (l_receiptdate   Parallel Hash  (cost=313722.45..313722.45 rows=3750045 width=20) (actual time=2011.518..2011.518 rows=3000000 loops=5)\n                                       Buckets: 65536  Batches: 256  Memory Usage: 3840kB\n                                       -&gt;  Parallel Seq Scan on orders  (cost=0.00..313722.45 rows=3750045 width=20) (actual time=0.029..995.948 rows=3000000 loops=5)\n Planning Time: 0.977 ms\n Execution Time: 7923.770 ms<\/code><\/pre>\n<p><\/p>\n<p>Query 12 from TPC-H clearly demonstrates a parallel hash join. Each worker process contributes to creating a common hash table.<\/p>\n<p><\/p>\n<h3 id=\"soedinenie-sliyaniem--merge-join\">Apvieno\u0161anas oper\u0101cija \u2014 Merge Join<\/h3>\n<p><\/p>\n<p>Apvieno\u0161anas oper\u0101cija p\u0113c savas b\u016bt\u012bbas nav paral\u0113la. Neuztraucieties, ja tas ir p\u0113d\u0113jais piepras\u012bjuma posms \u2014 tas joproj\u0101m var tikt izpild\u012bts paral\u0113li.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">-- Vaic\u0101jums 2 no TPC-H\nexplain (izmaksas izsl\u0113gtas) select s_acctbal, s_name, n_name, p_partkey, p_mfgr, s_address, s_phone, s_comment\nfrom    part, supplier, partsupp, nation, region\nwhere\n        p_partkey = ps_partkey\n        and s_suppkey = ps_suppkey\n        and p_size = 36\n        and p_type like &#039;%BRASS&#039;\n        and s_nationkey = n_nationkey\n        and n_regionkey = r_regionkey\n        and r_name = &#039;AMERIKA&#039;\n        and ps_supplycost = (\n                select\n                        min(ps_supplycost)\n                from    partsupp, supplier, nation, region\n                where\n                        p_partkey = ps_partkey\n                        and s_suppkey = ps_suppkey\n                        and s_nationkey = n_nationkey\n                        and n_regionkey = r_regionkey\n                        and r_name = &#039;AMERIKA&#039;\n        )\norder by s_acctbal desc, n_name, s_name, p_partkey\nLIMIT 100;\n                                                VAIC\u0100JUMA PL\u0100NS\n----------------------------------------------------------------------------------------------------------\n Limit\n   -&amp;gt;  Sort\n         Sort Key: supplier.s_acctbal DESC, nation.n_name, supplier.s_name, part.p_partkey\n         -&amp;gt;  Merge Join\n               Merge Cond: (part.p_partkey = partsupp.ps_partkey)\n               Join Filter: (partsupp.ps_supplycost = (SubPlan 1))\n               -&amp;gt;  Gather Merge\n                     Workers Planned: 4\n                     -&amp;gt;  Parallel Index Scan using &lt;strong&gt;part_pkey&lt;\/strong&gt; uz part\n                           Filtrs: (((p_type)::text ~~ &#039;%BRASS&#039;::text) AND (p_size = 36))\n               -&amp;gt;  Materialize\n                     -&amp;gt;  Sort\n                           Sort Key: partsupp.ps_partkey\n                           -&amp;gt;  Nested Loop\n                                 -&amp;gt;  Nested Loop\n                                       Join Filter: (nation.n_regionkey = region.r_regionkey)\n                                       -&amp;gt;  Seq Scan on region\n                                             Filtrs: (r_name = &#039;AMERIKA&#039;::bpchar)\n                                       -&amp;gt;  Hash Join\n                                             Hash Cond: (supplier.s_nationkey = nation.n_nationkey)\n                                             -&amp;gt;  Seq Scan on supplier\n                                             -&amp;gt;  Hash\n                                                   -&amp;gt;  Seq Scan on nation\n                                 -&amp;gt;  Index Scan using idx_partsupp_suppkey on partsupp\n                                       Index Cond: (ps_suppkey = supplier.s_suppkey)\n               SubPlan 1\n                 -&amp;gt;  Aggregate\n                       -&amp;gt;  Nested Loop\n                             Join Filter: (nation_1.n_regionkey = region_1.r_regionkey)\n                             -&amp;gt;  Seq Scan on region region_1\n                                   Filtrs: (r_name = &#039;AMERIKA&#039;::bpchar)\n                             -&amp;gt;  Nested Loop\n                                   -&amp;gt;  Nested Loop\n                                         -&amp;gt;  Index Scan using idx_partsupp_partkey on partsupp partsupp_1\n                                               Index Cond: (part.p_partkey = ps_partkey)\n                                         -&amp;gt;  Index Scan using supplier_pkey on supplier supplier_1\n                                               Index Cond: (s_suppkey = partsupp_1.ps_suppkey)\n                                   -&amp;gt;  Index Scan using nation_pkey on nation nation_1\n                                         Index Cond: (n_nationkey = supplier_1.s_nationkey)<\/code><\/pre>\n<p><\/p>\n<p>Noda &#171;Merge Join&#187; atrodas virs &#171;Gather Merge&#187;. T\u0101d\u0113\u013c apvieno\u0161ana neizmanto paral\u0113lo apstr\u0101di. Bet noda &#171;Parallel Index Scan&#187; tom\u0113r pal\u012bdz ar segmentu <code>part_pkey<\/code>.<\/p>\n<p><\/p>\n<h3 id=\"soedinenie-po-sekciyam\">Apvieno\u0161ana p\u0113c sekcij\u0101m<\/h3>\n<p><\/p>\n<p>PostgreSQL 11 <noindex><a rel=\"nofollow\" href=\"http:\/\/ashutoshpg.blogspot.com\/2017\/12\/partition-wise-joins-divide-and-conquer.html\">apvieno\u0161ana p\u0113c sekcij\u0101m<\/a><\/noindex> p\u0113c noklus\u0113juma atsl\u0113gta: tai ir \u013coti d\u0101rga pl\u0101no\u0161ana. Tabulas ar l\u012bdz\u012bg\u0101m sekcij\u0101m var apvienot sekcija pa sekcijai. T\u0101d\u0113j\u0101di Postgres izmantos maz\u0101kas hash tabulas. Katras sekciju apvieno\u0161anas var b\u016bt paral\u0113las.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">tpch=# set enable_partitionwise_join=t;\ntpch=# explain (costs off) select * from prt1 t1, prt2 t2\nwhere t1.a = t2.b and t1.b = 0 and t2.b between 0 and 10000;\n                    QUERY PLAN\n---------------------------------------------------\n Append\n   -&gt;  Hash Join\n         Hash Cond: (t2.b = t1.a)\n         -&gt;  Seq Scan on prt2_p1 t2\n               Filter: ((b &gt;= 0) AND (b &lt;= 10000))\n         -&gt;  Hash\n               -&gt;  Seq Scan on prt1_p1 t1\n                     Filter: (b = 0)\n   -&gt;  Hash Join\n         Hash Cond: (t2_1.b = t1_1.a)\n         -&gt;  Seq Scan on prt2_p2 t2_1\n               Filter: ((b &gt;= 0) AND (b &lt;= 10000))\n         -&gt;  Hash\n               -&gt;  Seq Scan on prt1_p2 t1_1\n                     Filter: (b = 0)\ntpch=# set parallel_setup_cost = 1;\ntpch=# set parallel_tuple_cost = 0.01;\ntpch=# explain (costs off) select * from prt1 t1, prt2 t2\nwhere t1.a = t2.b and t1.b = 0 and t2.b between 0 and 10000;\n                        QUERY PLAN\n-----------------------------------------------------------\n Gather\n   Workers Planned: 4\n   -&gt;  Parallel Append\n         -&gt;  Parallel Hash Join\n               Hash Cond: (t2_1.b = t1_1.a)\n               -&gt;  Parallel Seq Scan on prt2_p2 t2_1\n                     Filter: ((b &gt;= 0) AND (b &lt;= 10000))\n               -&gt;  Parallel Hash\n                     -&gt;  Parallel Seq Scan on prt1_p2 t1_1\n                           Filter: (b = 0)\n         -&gt;  Parallel Hash Join\n               Hash Cond: (t2.b = t1.a)\n               -&gt;  Parallel Seq Scan on prt2_p1 t2\n                     Filter: ((b &gt;= 0) AND (b &lt;= 10000))\n               -&gt;  Parallel Hash\n                     -&gt;  Parallel Seq Scan on prt1_p1 t1\n                           Filter: (b = 0)<\/code><\/pre>\n<p><\/p>\n<p>Galvenais, ka apvieno\u0161ana p\u0113c sekcij\u0101m var b\u016bt paral\u0113la tikai tad, ja \u0161\u012bs sekcijas ir pietiekami lielas.<\/p>\n<p><\/p>\n<h3 id=\"parallelnoe-dopolnenie--parallel-append\">Paral\u0113lais papildin\u0101jums \u2014 Parallel Append<\/h3>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/parallel-plans.html#PARALLEL-APPEND\">Parallel Append<\/a><\/noindex> var tikt izmantots viet\u0101 da\u017e\u0101diem blokiem da\u017e\u0101dos darba procesos. Parasti tas notiek ar UNION ALL piepras\u012bjumiem. Tr\u016bkums \u2014 maz\u0101k paral\u0113lisms, jo katrs darba process apstr\u0101d\u0101 tikai 1 piepras\u012bjumu.<\/p>\n<p><\/p>\n<p>\u0160eit darbojas 2 darba procesi, lai gan ir iesp\u0113joti 4.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">tpch=# explain (costs off) select sum(l_quantity) as sum_qty from lineitem where l_shipdate &lt;= date &#039;1998-12-01&#039; - interval &#039;105&#039; day union all select sum(l_quantity) as sum_qty from lineitem where l_shipdate   Parallel Append\n         -&gt;  Aggregate\n               -&gt;  Seq Scan on lineitem\n                     Filter: (l_shipdate   Aggregate\n               -&gt;  Seq Scan on lineitem lineitem_1\n                     Filter: (l_shipdate &lt;= &#039;1998-08-18 00:00:00&#039;::timestamp without time zone)<\/code><\/pre>\n<p><\/p>\n<h3 id=\"samye-vazhnye-peremennye\">Svar\u012bg\u0101k\u0101s main\u012bg\u0101s v\u0113rt\u012bbas<\/h3>\n<p><\/p>\n<ul>\n<li>WORK_MEM ierobe\u017eo atmi\u0146as apjomu katram procesam, nevis tikai vaic\u0101jumiem: work_mem <em> procesi <\/em> savienojumi = \u013coti daudz atmi\u0146as.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER\"><code>max_parallel_workers_per_gather<\/code><\/a><\/noindex> \u2014 cik darba procesu izpildes programma izmantos paral\u0113lai apstr\u0101dei no pl\u0101na.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES\"><code>max_worker_processes<\/code><\/a><\/noindex> \u2014 piel\u0101go visp\u0101r\u0113jo darba procesu skaitu atbilsto\u0161i servera CPU kodolu skaitam.<\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES\"><code>max_parallel_workers<\/code><\/a><\/noindex> \u2014 tas pats, bet paral\u0113lajiem darba procesiem.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"itogi\">Secin\u0101jumi<\/h3>\n<p><\/p>\n<p>S\u0101kot ar 9.6 versiju, paral\u0113l\u0101 apstr\u0101de var iev\u0113rojami uzlabot sare\u017e\u0123\u012btu vaic\u0101jumu veiktsp\u0113ju, kas sken\u0113 daudz rindu vai indeksu. PostgreSQL 10 paral\u0113l\u0101 apstr\u0101de ir iesp\u0113jota p\u0113c noklus\u0113juma. Neaizmirstiet to atsl\u0113gt serveros ar lielu OLTP slodzi. Sekvenci\u0101ras sken\u0113\u0161anas vai indeksu sken\u0113\u0161ana pat\u0113r\u0113 \u013coti daudz resursu. Ja neizpild\u0101t p\u0101rskatu uz visu datu kopu, vaic\u0101jumi var tikt efekt\u012bv\u0101ki, vienk\u0101r\u0161i pievienojot tr\u016bksto\u0161os indeksus vai izmantojot pareizu sekciju.<\/p>\n<p><\/p>\n<h3 id=\"ssylki\">Saites<\/h3>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/how-parallel-query-works.html\">https:\/\/www.postgresql.org\/docs\/11\/how-parallel-query-works.html<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.postgresql.org\/docs\/11\/parallel-plans.html\">https:\/\/www.postgresql.org\/docs\/11\/parallel-plans.html<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/ashutoshpg.blogspot.com\/2017\/12\/partition-wise-joins-divide-and-conquer.html\">http:\/\/ashutoshpg.blogspot.com\/2017\/12\/partition-wise-joins-divide-and-conquer.html<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/rhaas.blogspot.com\/2016\/04\/postgresql-96-with-parallel-query-vs.html\">http:\/\/rhaas.blogspot.com\/2016\/04\/postgresql-96-with-parallel-query-vs.html<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/amitkapila16.blogspot.com\/2015\/11\/parallel-sequential-scans-in-play.html\">http:\/\/amitkapila16.blogspot.com\/2015\/11\/parallel-sequential-scans-in-play.html<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/write-skew.blogspot.com\/2018\/01\/parallel-hash-for-postgresql.html\">https:\/\/write-skew.blogspot.com\/2018\/01\/parallel-hash-for-postgresql.html<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"http:\/\/rhaas.blogspot.com\/2017\/03\/parallel-query-v2.html\">http:\/\/rhaas.blogspot.com\/2017\/03\/parallel-query-v2.html<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/blog.2ndquadrant.com\/parallel-monster-benchmark\/\">https:\/\/blog.2ndquadrant.com\/parallel-monster-benchmark\/<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/blog.2ndquadrant.com\/parallel-aggregate\/\">https:\/\/blog.2ndquadrant.com\/parallel-aggregate\/<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/www.depesz.com\/2018\/02\/12\/waiting-for-postgresql-11-support-parallel-btree-index-builds\/\">https:\/\/www.depesz.com\/2018\/02\/12\/waiting-for-postgresql-11-support-parallel-btree-index-builds\/<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/jWIOZzezbb8\">Paral\u0113lisms PostgreSQL 11<\/a><\/noindex><\/li>\n<\/ul>\n<p>Avots: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/southbridge\/blog\/446706\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0426\u041f \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u044f\u0434\u0435\u0440. \u0413\u043e\u0434\u0430\u043c\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u044b\u043b\u0430\u043b\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043e\u0442\u0447\u0435\u0442\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0443 \u0441\u0442\u0440\u043e\u043a \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u043e\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0426\u041f, \u0438 \u0432 PostgreSQL \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 9.6. \u041f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u043e\u0441\u044c 3 \u0433\u043e\u0434\u0430, \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u2014 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u044d\u0442\u0430\u043f\u0430\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":22879,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-30900","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.4 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0426\u041f \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u044f\u0434\u0435\u0440.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/parallelnye-zaprosy-v-postgresql\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"lv_LV\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 PostgreSQL | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0426\u041f \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u044f\u0434\u0435\u0440.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/parallelnye-zaprosy-v-postgresql\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:38:02+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:38:02+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47 Paral\u0113lie vaic\u0101jumi PostgreSQL | ProHoster","description":"M\u016bsdienu CPU ir \u013coti daudz kodolu.","canonical_url":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/parallelnye-zaprosy-v-postgresql","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"lv_LV","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0432 PostgreSQL | ProHoster","og:description":"\u0412 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0426\u041f \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u044f\u0434\u0435\u0440.","og:url":"https:\/\/prohoster.info\/lv\/blog\/administrirovanie\/parallelnye-zaprosy-v-postgresql","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:38:02+00:00","article:modified_time":"2019-10-31T18:38:02+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"30900","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 03:34:04","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:27:06","updated":"2026-01-21 03:34:04","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts\/30900","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/comments?post=30900"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/posts\/30900\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/media\/22879"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/media?parent=30900"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/categories?post=30900"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/lv\/wp-json\/wp\/v2\/tags?post=30900"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}