Autor Zpráva
Stroganov
Profil *
Zdravím,

mám databázovú tabuľku v postgre s cca. 320 000 riadkami, kde každú noc beží okrem iného príkaz:

UPDATE tabulka
SET stlpec1 = stlpec2

Teraz update trvá 90 - 200 sekúnd. Dal by sa prosím nejako optimalizovať? Tabuľka má asi 8 ďalších stĺpcov.

Indexy sú v tabuľke skoro na každom stĺpci, ale na stlpec1 ani na stlpec2 žiadny index nie je.

Dátové typy oboch stĺpcov sú varchar. Dĺžka pevne daná, 35 znakov.

Vopred ďakujem.
Kajman
Profil
Je vůbec někdy žádoucí, aby v obou sloupcích byla jiná hodnota?

Pomůže v update omezit ve where jen ty řádky, kde je stlpec1 jiný než stlpec2?

Jinak si myslím, že to bude hlavně o rychlosti disku.
anonym_
Profil *
Kajman:
Je vůbec někdy žádoucí, aby v obou sloupcích byla jiná hodnota?
Skoro bych si tipl, že to je pokud o tabulku stylem "dnešní hodnota | včerejší hodnota", kdy se v noci nastavuje "dnešní" na "včerejší" a čeká se na novou. Alespoň tak mi to dotaz evokoval od začátku, ale s rychlostí jsem poradil neuměl.
juriad
Profil
Také mám pocit, že výkon bude omezený rychlostí zápisu než čtení, tedy důležité bude omezení počtu updatnutých řádků. Přidání podmínky where sloupec1 != sloupec2 nemůže uškodit.

Pokud je to scénář jak naznačuje anonym, bylo by možná lepší vytvořit novou tabulku a starou zahodit - vacuum bude mít méně práce, lepší lokalita dat na disku pokud se nejedná o SSD.

Další možností je použít trigger, který při změně dnešní hodnoty překopíruje starou hodnotu do druhého sloupce. Tím by se kompletně odstranila potřeba pro noční updaty. Pokud updatů může přijít víc za jeden den, je možné přidat další sloupec, který si udržuje informaci o tom, kdy byl sloupec2 naposledy upravený a v triggeru přidat logiku, která provede odkopírování jen poprvé každý den.
tttttttttt
Profil *
Není to UUID? Má sice délku 36, ale je to podezřele blízko.

Na cvičných datech mi trvá update milionu řádku v tabulce s 10 textovými sloupci 10 s. Změřil bych, proč to máš výrazně pomalejší.

- Jak dlouho trvá update, pokud smažeš indexy?
- Jak dlouho trvá update, pokud budou v tabulce jen ty dva sloupce?

Jinak bych taky zkoušel omezit počet aktualizovaných řádků. Nejjednodušší mi přijde přidat sloupec updated_at, trigger, který ho nastaví na čas poslední změny, a podmínku, která omezí update jen na změněné řádky.

O fous rychlejší může být datový typ TEXT, ale měřitelné to asi nebude.
Stroganov
Profil *
Bez indexov - 3 sekundy
S indexmi - 150 sekúnd
Kajman
Profil
A opravdu žádný index ani klíč neobsahuje sloupec stlpec1? Nebo nejsou na té tabulce triggery, které po úpravě stlpec1 upravují jiný sloupec?
tttttttttt
Profil *
Stroganov:
Nastav té tabulce fillfactor na menší hodnotu, třeba 50. Pokud je místo ve stejné stránce, kde se řádek nachází, zapíše se nový řádek taky tam a nemusí se měnit index. Ve výsledku tipuju, že to bude většinou rychlé a pomalé jen někdy. když místo ve stránce dojde. Co znamená "někdy" bude záležet na nastavení fill factoru.

Klíčová slova jsou fill factor a heap-only-tuples (HOT).

Taky může být rychlejší ty indexy smazat a vytvořit znovu.
Stroganov
Profil *
Kajman:
A opravdu žádný index ani klíč neobsahuje sloupec stlpec1?

Na stlpec1 index skutočne nie je, ale teraz som našiel index na stlpec2, ospravedlňujem sa za chybné tvrdenie v prvom príspevku.

tttttttttt:
S fillfactor sa pohrám, páči sa mi aj idea „Taky může být rychlejší ty indexy smazat a vytvořit znovu.“.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0