Fórum Root.cz
Hlavní témata => Server => Téma založeno: ondrej _ 03. 07. 2023, 17:06:41
-
Je mozne PostgreSQL donutit aby v konkretnom query vzdy pouzil rovnaky query plan?
Mam problem s jednym query, kde sa vyhladavaju zaznamy aj podla typu spravy. Zistil som, ze PostgreSQL pri danom sql query pouziva dva rozne query plany.
Jeden je rychly a druhy velmi pomaly. Pri tom rychlom sa pouziju indexy, ktore boli pre toto query vytvorene. Pri pomalom sa nepouzije a PostgeSQL skenuje celu tabulku za pomoci primarneho kluca(ID je v primarnom kluci)
PostgreSQL ten pomaly query plan pouzije v pripade ked pocet zaznamov s danym typom je nizky alebo celkovy pocet zazamov je nizky.
Priklad.
1.Pouzijem typ spravy XML, ktoreho je v databaze malo a pouzijem maly rozsah datumov aby som prehladaval maly pocet zaznamov. Query je pomale(prehladavanie 15 tis. zaznamov mu trva 5-6s). Postupne zvecsujem rozsah az v urcitom momente sa sql zrychli(cas klesne na uroven jednej skundy). Je to vdaka tomu, ze sa zmenil query plan v ktorom sa okrem ineho pouzije ocakvany index.
2.Ak pouzijem typ spravy JSON, ktoreho je v databaze vecsina, tak sa to chova rovnako az na to, ze sql sa zrychli az ovela neskor.
V prvom pripade sqlko zrychli na urovni +- 100 tisic zaznamov. V druhom pripade az ked sa pohybujeme v stovkach tisic zaznamov.
Query obsahuje viacere joiny a typ spravy je ulozeny v jsone(stlpec typu jsonb). PostgreSQL je verzie 11.
SQL-ko tu bohuzial nemozem zdielat. Urcite sa da vylepsit ale mam obmedzene moznosti, co si mozem dovolit a som presvedceny ak by PostgreSQL pouzival stale rovnaky query plan, tak by to pomohlo.
Studoval som, hladal som, skusal som ale zatial som neprisiel na to ako presvedcit PostgreSQL aby ten pomaly query plan nepouzival.
Za kazdu radu budem vdacny.
-
Těch důvodů proč se použije špatný plán může být vícero. Od špatných odhadů až po nehomogenní uložení dat. Bez znalosti dotazu a prováděcího plánu se nedá říct vůbec nic. Postgres žádné fixování plánů nemá. Pokud nemůžete zveřejnit informace, obraťte se na svůj placený support.
-
Zkuste snížit hodnotu random_page_cost
-
Zkuste snížit hodnotu random_page_cost
Pokud oba plány používají index, tak to nepomůže. Navíc pokud nemáte SSD, tak je snížení random_page_cost dost problematické, něco zrychlí, něco může zase fatálně zpomalit. Základem je pochopit proč se použije špatný plán, slepě mačkat všechna tlačítka většinou nepomůže.
-
Ze pry bys nemel, ale muzes pouzit SET SESSION enable_seqscan=false
-
První co mi nedá: je to opravdu pokaždé textově stejné SQL (a ty vyhledávací parametry se předávají nabindovanou proměnnou), nebo se do něj parametry stringově naconcatujou?
Tj "select ... where datum between ? and ?" vs "select ... where datum between to_date('2023-01-01') and to_date('2023-02-01')"
(jestli to není stejný string, tak se klidně může nacacheovat úplně jiný plán ...)
-
První co mi nedá: je to opravdu pokaždé textově stejné SQL (a ty vyhledávací parametry se předávají nabindovanou proměnnou), nebo se do něj parametry stringově naconcatujou?
Tj "select ... where datum between ? and ?" vs "select ... where datum between to_date('2023-01-01') and to_date('2023-02-01')"
(jestli to není stejný string, tak se klidně může nacacheovat úplně jiný plán ...)
Bacha, Postgres není Oracle. Nemá implicitní plan cache.
-
Zkuste snížit hodnotu random_page_cost
Pokud oba plány používají index, tak to nepomůže.
Já jsem z toho jak je to popsané pochopil že index se v jednom plánu nepoužívá a tento plán se volí se dokud je v tabulce málo záznamů. To je přesně případ ve kterém mi pomohlo snížit hodnotu random_page_cost - samozřejmě netvrdím že to pomůže i v tomto případě, ale připadá mi že by stálo za to to zkusit.
-
Zkuste snížit hodnotu random_page_cost
Pokud oba plány používají index, tak to nepomůže.
Já jsem z toho jak je to popsané pochopil že index se v jednom plánu nepoužívá a tento plán se volí se dokud je v tabulce málo záznamů. To je přesně případ ve kterém mi pomohlo snížit hodnotu random_page_cost - samozřejmě netvrdím že to pomůže i v tomto případě, ale připadá mi že by stálo za to to zkusit.
Ja to pochopil jinak - viz věta "Pri pomalom sa nepouzije a PostgeSQL skenuje celu tabulku za pomoci primarneho kluca(ID je v primarnom kluci)". Nicmeně jelikož tazatel nemůže zveřejnit prováděcí plány, tak stejně všichni tu střílíme naslepo, což je jen ztráta času. Kdo ví, co tam je za problém - také to může být nezvakuovaná nebo bloatnutá tabulka, nebo chybějící více sloupcová statistika.
-
Oba plany pouzivaju index.
V pripade pomaleho query
Index Scan using dep_document_pkey on dep_document (cost=0.29..0.36 rows=1 width=16) (actual time=0.234..0.234 rows=0 loops=160742)
V pripade rychleho queru
Bitmap Index Scan on idx_doc_type_format (cost=0.00..80.48 rows=1607 width=0) (actual time=0.531..0.531 rows=4115 loops=1)
Podotykam, tie query plany su dost odlisne.
Ako som pisal, tak od urciteho mnozstva zaznamov sa pouziva ten druhy query plan. Kedy zalezi od typu, ktory hladam. Ak je to menej bezny typ, tak sa to preklopi skor.
Je to zakazdym textovo rovnake SQL. Zmenim typ hladaneho dokumentu a pouzije sa iny plan.
Hladany typ je ulozeny v JSONB stlpci a dany index obsahuje kombinaciu troch klucov z json-u ukladaneho do tohto stlpca.
V sqlku su este dalsie podmienky s inymi klucmi z jsonu. 3 podmienky sa zhoduju s tymi v indexe a jedna podmienka nie.
Prvom pomalom pripade spoji vsetky podmienky a vyhladava zaznamy, ktore splnaju vsetky podmienky v jednom kroku za pomoci primarneho kluca.
V druhom pripade je to rozdelene na 2 kroky. V prvom kroku pouzije index a 3 podmienky s klucami, ktore su v danom indexe. Pomocou toho indexu odfiltruje zaznamy, co trva velmi kratko. Nasledne este odfiltruje zaznamy podla zostavajucej podmienky, co je tiez rychle.
Nemam ziadne skusenosti s indexami a hladanim v JSON-e. Vypisal som si aj statistiky a vyzera, ze udrzba tabuliek pravidelne prebieha.
Spustil som ju aj rucne a nepomoholo.
Postupil som s danym problemom
Podarilo sa mi upravit SQL-ko. Skusal som rozne kombinacie. Pri pouziti subselectu sa uz stale pouzivaju ocakavane indexy a zaroven sa SQL zrychlilo. Zrychlilo sa vo vsetkych pripadoch. Nove SQL je dokonca rychlejsie aj ako povodne, ked sa pouzivali indexy.
Nove SQL vyzera hrozne/zlozitejsie oproti povodnemu ale funguje to.
Rad by som sa ale dozvedel viacej o PostgreSQL a jeho spravani sa v takomto pripade. Viete mi poradit dobry zdroj, ktory sa zaobera touto tematikou?
-
Muzete ukazat cele provadeci plany? https://explain.depesz.com/ umi anonymizaci. Evidentne tam mate nested loop nad primarnim klicem. Zkontrolujte si jestli nemate ten index bloatly, pripadne muzete penalizovat nested loop - `set enable_nestloop to off`. Z toho zlomku, co jste ukazal by mozna mohl pomoct podmineny index. Postgres pri odhadech nejde na 0, nicmene ve vasem pripade tam ty hodnoty, ktere se hledaji, evidentne nemate.
V zasade jde o to pochopit, jak funguje optimalizace dotazu - v pripade modernich SQL databazi optimalizace zalozena na statistikach, a v cem a jak muze tato optimalizace chybovat. A pak se snazite a) eliminovat chyby, nebo b) vytvarite prostor nebo zuzujete prostor pro optimalizaci. Jednodussi dotaz vytvari mensi prostor pro optimalizaci, komplexnejsi vetsi prostor pro optimalizaci. Na internetu nic moc uceleneho nenajdete, alespon ja o tom nevim. Jsou dobre prezentace, ale vetsinou zamerene na jeden konkretni problem (protoze se vetsinou musite vejit do limitu 50 nebo 90 minut). Videl jsem par knizek, a mam i "PostgreSQL Query Optimization, Dombrovskaya, Novikov, Bailliekova", ktera je slusna a je urcena pro zacatecniky (jak znam typicke znalosti vyvojaru pouzivajicich databaze, tak vyjma par expertu, jsou prakticky vsichni vecni zacatecnici). Pak je to o zkusenostech. Ja se tim zivim. Budto skolim, anebo resim performance problemy. Za 20 let uz si pak clovek udela docela prehled (a jeste se motam kolem vyvoje Postgresu, i kdyz hodne daleko k optimalizaci). Tady v CR (i svetove) je spicka Tomas Vondra, ktery napsal do Postgresu podporu vicesloupcovych statistik, ted se mota kolem BRIN indexu a replikace. Muzete zkusit hledat nejake jeho prezentace na netu.
-
Oba plany pouzivaju index.
V pripade pomaleho query
Index Scan using dep_document_pkey on dep_document (cost=0.29..0.36 rows=1 width=16) (actual time=0.234..0.234 rows=0 loops=160742)
Ten index scan u vás není extra rychlý - ještě bych tabulku zvakuoval (což by se mělo dělat jako první krok při řešení performance problému), a pak zkontroloval nastavení shared_buffers a random_page_cost. Tak se může chovat podstřelené nastavení random_page_cost. Na mém notebooku mám o 2 řády rychlejší čas.
-
Ak ich je mozne anonymizovat, tak ich ukazem. Mal by som ma niekde zjednodusenu verziu orginal SQL, kde sa ten problem rovnako prejavoval.
To bola vzorka z uz neviem presne akej verzie. Skusal som rozne hodnoty a porovnaval plany ked som sa snazil pochopit preco sa to tak chova.
(jak znam typicke znalosti vyvojaru pouzivajicich databaze, tak vyjma par expertu, jsou prakticky vsichni vecni zacatecnici).
S tymto musim suhlasit. Motal som sa trochu okolo databaz v minulosti a teraz po rokoch som sa znovu k tomu dostal a po tyzdni studia, skusania si pripadam ako expert oproti kolegom vratane senior/tech lead.
Ten index scan u vás není extra rychlý - ještě bych tabulku zvakuoval (což by se mělo dělat jako první krok při řešení performance problému), a pak zkontroloval nastavení shared_buffers a random_page_cost. Tak se může chovat podstřelené nastavení random_page_cost. Na mém notebooku mám o 2 řády rychlejší čas.
Vacuum bola prva vec, ktoru som skusil. Nemalo to ziaden vplyv. Skusal som aj updatnut statistiky, ci PostgreSQL si to potom nerozmysli, rovnako bez vysledku. Nastavenia databazy som neriesil. Databaza bezi neviem kde a neviem na com. Riesit to by bolo na 2 tyzdne vysvetlovania a spekulovania ci to je nutne a obav z produkcneho nasadenia akejkolvek takejto zmeny. Je to aj z dovodu vyssie spomenuteho developerskeho vecneho zaciatocnictva a databazy vnimanej ako nutne zlo.
Mam obmedzene moznosti a tak sa snazim s tym urobit co sa da.
-
Vacuum bola prva vec, ktoru som skusil. Nemalo to ziaden vplyv. Skusal som aj updatnut statistiky, ci PostgreSQL si to potom nerozmysli, rovnako bez vysledku. Nastavenia databazy som neriesil. Databaza bezi neviem kde a neviem na com. Riesit to by bolo na 2 tyzdne vysvetlovania a spekulovania ci to je nutne a obav z produkcneho nasadenia akejkolvek takejto zmeny. Je to aj z dovodu vyssie spomenuteho developerskeho vecneho zaciatocnictva a databazy vnimanej ako nutne zlo.
Mam obmedzene moznosti a tak sa snazim s tym urobit co sa da.
Ono jde o to, že pokud máte default shared_buffers 128MB a ta tabulka se do této velikosti nevejde, navíc běžíte na kdoví jakém železe, jak sám píšete, tak index scan může být dost pomalý. Navíc si někdo může přečíst radu typu sniž random_page_cost třeba na nějaký extrém typu 1, a pak optimalizátor může dělat dost divné věci. To jestli je dotaz rychlý ovlivňuje prováděcí plán, aktuální zdraví tabulek a indexů a částečně i konfigurace. Ta konfigurace spíš v extrémech - při rozumném nastavení a rozumném železe nemá velký vliv, ale setkáte se s šílemým nastavením (které u některých dotazů pomůže, ale u jiných hodně uškodí), a setkáte se i s šíleným železem (patologicky poddimenzované železo nebo divně nízký výkon IO nebo CPU (u virtualizace je to docela časté)).
-
Tu je pomaly query plan
https://explain.depesz.com/s/VuoL
Tu je rychly query plan
https://explain.depesz.com/s/UALc
Rozdiel medzi nimi je ten, ze sa zmenil len vyhladavany typ dokumentu.
Podotykam, ze sa jedna o zjednodusenu verziu povodneho SQL, kde sa to chova rovnako.
-
Tu je pomaly query plan
https://explain.depesz.com/s/VuoL
Ty odkazy nejsou validni
-
Nevies mi poradit ako funguje ta stranka?
Nahral som to tam, vybral som moznost anonymizovat a klikol na Submit. Cakal som, ze tie query plany budu na tej adrese dokial ich nezmazem cez link uvedeny na stranke.
-
netusim ako ta stranka funguje.
Posielam anonymizovane plany
Fast
Unique (cost=72877.07..72877.13 rows=1 width=234) (actual time=0.107..0.121 rows=0 loops=1)
-> Sort (cost=72877.07..72877.08 rows=1 width=234) (actual time=0.104..0.116 rows=0 loops=1)
Sort Key: romeo_echo_whiskey.quebec_seven, romeo_echo_whiskey.mike_alpha, romeo_echo_whiskey.quebec_whiskey, romeo_echo_whiskey.three, romeo_echo_whiskey.foxtrot_yankee, romeo_echo_whiskey.whiskey_romeo, romeo_echo_whiskey.charlie, romeo_echo_whiskey.tango_seven, romeo_echo_whiskey.quebec_bravo, romeo_echo_whiskey.juliet, romeo_echo_whiskey.seven_papa, romeo_echo_whiskey.romeo_hotel, romeo_echo_whiskey.romeo_echo_quebec, romeo_echo_whiskey.victor, romeo_echo_whiskey.bravo_zulu, romeo_echo_whiskey.quebec_echo, romeo_echo_whiskey.yankee, romeo_echo_whiskey.tango_lima, romeo_echo_whiskey.whiskey_yankee, romeo_echo_whiskey.uniform
Sort Method: quicksort Memory: 25kB
-> Nested Loop (cost=566.52..72877.06 rows=1 width=234) (actual time=0.082..0.093 rows=0 loops=1)
-> Nested Loop (cost=566.10..72629.32 rows=487 width=234) (actual time=0.079..0.089 rows=0 loops=1)
-> Bitmap Heap Scan on whiskey_four (cost=8.85..12.91 rows=1 width=16) (actual time=0.052..0.060 rows=2 loops=1)
Recheck Cond: (((((((foxtrot_juliet -> 'papa_november'::text) -> 'quebec_november'::text) ->> 'oscar'::text))::text = 'bravo_november'::text) AND (((((foxtrot_juliet -> 'papa_november'::text) -> 'quebec_november'::text) ->> 'hotel'::text))::text = 'seven_three'::text) AND (((foxtrot_juliet ->> 'foxtrot_kilo'::text))::text = 'seven_alpha'::text)) OR ((((((foxtrot_juliet -> 'golf_six'::text) -> 'quebec_november'::text) ->> 'oscar'::text))::text = 'bravo_november'::text) AND (((((foxtrot_juliet -> 'golf_six'::text) -> 'quebec_november'::text) ->> 'hotel'::text))::text = 'seven_three'::text) AND (((foxtrot_juliet ->> 'foxtrot_kilo'::text))::text = 'six_seven'::text)))
Filter: ((juliet)::text = ANY ('romeo_oscar'::text[]))
Rows Removed by Filter: 2
Heap Blocks: exact=4
-> BitmapOr (cost=8.85..8.85 rows=1 width=0) (actual time=0.039..0.043 rows=0 loops=1)
-> Bitmap Index Scan on lima_yankee (cost=0.00..4.42 rows=1 width=0) (actual time=0.027..0.027 rows=4 loops=1)
Index Cond: ((((((foxtrot_juliet -> 'papa_november'::text) -> 'quebec_november'::text) ->> 'oscar'::text))::text = 'bravo_november'::text) AND (((((foxtrot_juliet -> 'papa_november'::text) -> 'quebec_november'::text) ->> 'hotel'::text))::text = 'seven_three'::text) AND (((foxtrot_juliet ->> 'foxtrot_kilo'::text))::text = 'seven_alpha'::text))
-> Bitmap Index Scan on india_hotel (cost=0.00..4.42 rows=1 width=0) (actual time=0.009..0.010 rows=0 loops=1)
Index Cond: ((((((foxtrot_juliet -> 'golf_six'::text) -> 'quebec_november'::text) ->> 'oscar'::text))::text = 'bravo_november'::text) AND (((((foxtrot_juliet -> 'golf_six'::text) -> 'quebec_november'::text) ->> 'hotel'::text))::text = 'seven_three'::text) AND (((foxtrot_juliet ->> 'foxtrot_kilo'::text))::text = 'six_seven'::text))
-> Bitmap Heap Scan on romeo_echo_whiskey (cost=557.24..72388.42 rows=22798 width=234) (actual time=0.008..0.009 rows=0 loops=2)
Recheck Cond: (tango_seven = whiskey_four.quebec_seven)
-> Bitmap Index Scan on lima_four (cost=0.00..551.54 rows=22798 width=0) (actual time=0.006..0.006 rows=0 loops=2)
Index Cond: (tango_seven = whiskey_four.quebec_seven)
-> Index Scan using seven_five on golf_sierra (cost=0.43..0.51 rows=1 width=16) (never executed)
Index Cond: (quebec_seven = romeo_echo_whiskey.mike_alpha)
Filter: ((kilo >= 'mike_four'::timestamp without time zone) AND (kilo <= 'papa_uniform'::timestamp without time zone) AND (six_delta = 'romeo_echo_charlie'::uuid) AND (india_four = 'india_lima'::uuid))
Planning time: 0.651 ms
Execution time: 0.211 ms
Slow
Unique (cost=84298.41..84298.88 rows=9 width=234) (actual time=41216.659..41216.671 rows=0 loops=1)
-> Sort (cost=84298.41..84298.43 rows=9 width=234) (actual time=41216.657..41216.667 rows=0 loops=1)
Sort Key: romeo_echo_whiskey.quebec_seven, romeo_echo_whiskey.mike_alpha, romeo_echo_whiskey.quebec_whiskey, romeo_echo_whiskey.three_sierra, romeo_echo_whiskey.foxtrot_yankee, romeo_echo_whiskey.whiskey_romeo, romeo_echo_whiskey.charlie, romeo_echo_whiskey.tango_seven, romeo_echo_whiskey.quebec_bravo, romeo_echo_whiskey.juliet, romeo_echo_whiskey.seven_papa, romeo_echo_whiskey.romeo_hotel, romeo_echo_whiskey.romeo_echo_quebec, romeo_echo_whiskey.victor, romeo_echo_whiskey.bravo_zulu, romeo_echo_whiskey.quebec_echo, romeo_echo_whiskey.yankee, romeo_echo_whiskey.tango_lima, romeo_echo_whiskey.whiskey_yankee, romeo_echo_whiskey.uniform
Sort Method: quicksort Memory: 25kB
-> Nested Loop (cost=6.69..84298.27 rows=9 width=234) (actual time=41216.636..41216.644 rows=0 loops=1)
-> Nested Loop (cost=6.40..84136.15 rows=453 width=234) (actual time=0.036..1566.054 rows=160730 loops=1)
-> Index Scan using india_foxtrot on golf_sierra (cost=0.56..525.98 rows=130 width=16) (actual time=0.017..427.026 rows=53864 loops=1)
Index Cond: ((six_delta = 'romeo_echo_charlie'::uuid) AND (india_four = 'india_lima'::uuid) AND (kilo >= 'mike_four'::timestamp without time zone) AND (kilo <= 'papa_uniform'::timestamp without time zone))
-> Bitmap Heap Scan on romeo_echo_whiskey (cost=5.85..641.50 rows=166 width=234) (actual time=0.008..0.013 rows=3 loops=53864)
Recheck Cond: (mike_alpha = golf_sierra.quebec_seven)
Heap Blocks: exact=75186
-> Bitmap Index Scan on quebec_uniform (cost=0.00..5.80 rows=166 width=0) (actual time=0.005..0.005 rows=3 loops=53864)
Index Cond: (mike_alpha = golf_sierra.quebec_seven)
-> Index Scan using three_foxtrot on whiskey_four (cost=0.29..0.36 rows=1 width=16) (actual time=0.245..0.245 rows=0 loops=160730)
Index Cond: (quebec_seven = romeo_echo_whiskey.tango_seven)
Filter: (((juliet)::text = ANY ('romeo_oscar'::text[])) AND (((((((foxtrot_juliet -> 'papa_november'::text) -> 'quebec_november'::text) ->> 'oscar'::text))::text = 'bravo_november'::text) AND (((((foxtrot_juliet -> 'papa_november'::text) -> 'quebec_november'::text) ->> 'hotel'::text))::text = 'sierra'::text) AND (((foxtrot_juliet ->> 'foxtrot_kilo'::text))::text = 'seven_alpha'::text)) OR ((((((foxtrot_juliet -> 'golf_six'::text) -> 'quebec_november'::text) ->> 'oscar'::text))::text = 'bravo_november'::text) AND (((((foxtrot_juliet -> 'golf_six'::text) -> 'quebec_november'::text) ->> 'hotel'::text))::text = 'sierra'::text) AND (((foxtrot_juliet ->> 'foxtrot_kilo'::text))::text = 'six_seven'::text))))
Rows Removed by Filter: 1
Planning time: 0.643 ms
Execution time: 41216.752 ms
-
Nevies mi poradit ako funguje ta stranka?
Nahral som to tam, vybral som moznost anonymizovat a klikol na Submit. Cakal som, ze tie query plany budu na tej adrese dokial ich nezmazem cez link uvedeny na stranke.
Mne to tak funguje viz https://explain.depesz.com/s/8nwt
-
-> Index Scan using india_foxtrot on golf_sierra (cost=0.56..525.98 rows=130 width=16) (actual time=0.017..427.026 rows=53864 loops=1)
Index Cond: ((six_delta = 'romeo_echo_charlie'::uuid) AND (india_four = 'india_lima'::uuid) AND (kilo >= 'mike_four'::timestamp without time zone) AND (kilo <= 'papa_uniform'::timestamp without time zone))
Tam je problém v brutálně špatném odhadu. Ale těžko říct jak by se dal ten odhad opravit. Za uuid bych na hodinu vyhazoval, a odhad x >= t1 and x <= t2 taky není nejšťastnější. Tady možná přepsat ten dotaz, aby se ten predikát nevyhodnocoval naráz. Možná by stálo přepsat tuu druhou podmínky na výskyt uvnitř časové range.
-
Za uuid bych na hodinu vyhazoval
Jak je toto mysleno - muzete rozvest?
-
Je možné přinutit PostgreSQL, aby v určitém dotazu používal vždy stejný plán dotazu. Můžete to provést nastavením konfiguračního parametru plan_cache_mode na hodnotu force . Tím dáte PostgreSQL pokyn, aby pro daný dotaz vždy použil první nalezený plán dotazu, i když to není nejefektivnější plán.
-
Za uuid bych na hodinu vyhazoval
Jak je toto mysleno - muzete rozvest?
V souvislosti s uuid jsem slyšel o dvou hlavních problémech - jsou u nich horší odhady - až na vyjímky negenerují rostoucí řadu, a vzhledem k tomu, že mají velký rozsah a typicky 2 po sobě vygenerované hodnoty se mohou hodně až brutálně lišit tak se při aktualizaci indexu mění velký počet datových stránek, což vede k intenzivnímu zápisu do transakčního logu. Neplatí to pro všechny typy uuid.
Viz https://www.cybertec-postgresql.com/en/uuid-serial-or-identity-columns-for-postgresql-auto-generated-primary-keys/ nebo https://www.2ndquadrant.com/en/blog/sequential-uuid-generators/
-
Je možné přinutit PostgreSQL, aby v určitém dotazu používal vždy stejný plán dotazu. Můžete to provést nastavením konfiguračního parametru plan_cache_mode na hodnotu force . Tím dáte PostgreSQL pokyn, aby pro daný dotaz vždy použil první nalezený plán dotazu, i když to není nejefektivnější plán.
To platí jen pro prepared statements nebo pro dotazy z PL/pgSQL - tedy pouze tam, kde se uplatní plan cache. Opět pozor - co se týče plan cache, tak Postgres je postavený úplně jinak než Oracle nebo MSSQL - nemá implicitní plan cache (vyjma dotazů z PL/pgSQL).
-
Za uuid bych na hodinu vyhazoval
Jak je toto mysleno - muzete rozvest?
V souvislosti s uuid jsem slyšel o dvou hlavních problémech - jsou u nich horší odhady - až na vyjímky negenerují rostoucí řadu, a vzhledem k tomu, že mají velký rozsah a typicky 2 po sobě vygenerované hodnoty se mohou hodně až brutálně lišit tak se při aktualizaci indexu mění velký počet datových stránek, což vede k intenzivnímu zápisu do transakčního logu. Neplatí to pro všechny typy uuid.
Viz https://www.cybertec-postgresql.com/en/uuid-serial-or-identity-columns-for-postgresql-auto-generated-primary-keys/ nebo https://www.2ndquadrant.com/en/blog/sequential-uuid-generators/
Díky.