sql >> Databáze >  >> RDS >> PostgreSQL

Aktualizace databázových řádků bez zamykání tabulky v PostgreSQL 9.2

MVCC

Za prvé, pokud se "normální operace" skládají z SELECT dotazy, model MVCC se o to postará automaticky. UPDATE neblokuje SELECT a naopak. SELECT vidí pouze potvrzená data (nebo to, co bylo provedeno ve stejné transakci), takže výsledek velkého UPDATE zůstane neviditelný pro ostatní transakce, dokud nebude dokončen (odsouhlasen).

Výkon / nadýmání

Pokud nemáte další objekty odkazující na tuto tabulku,
a nemáte souběžné operace zápisu (které by byly ztraceny!),
a můžete si dovolit velmi krátký exkluzivní zámek na stole,
a máte samozřejmě další místo na disku:
Zamykání můžete omezit na minimum vytvořením aktualizované verze tabulky na pozadí. Ujistěte se, že má vše být náhradní náhradou, pak originál zahoďte a přejmenujte dupe.

CREATE TABLE tbl_new (LIKE tbl_org INCLUDING CONSTRAINTS);

INSERT INTO tbl_new 
SELECT col_a, col_b, array[col] aS col_c
FROM   tbl_org;

Používám CREATE TABLE (LIKE .. INCLUDING CONSTRAINTS) , protože (zde cituji manuál):

Nenulová omezení se vždy zkopírují do nové tabulky. CHECK omezení budou zkopírována pouze v případě, že INCLUDING CONSTRAINTS je zadáno;jiné typy omezení nebudou nikdy zkopírovány.

Ujistěte se, že nový stůl je připraven. Potom:

DROP tbl_org;
ALTER TABLE tbl_new RENAME TO tbl_org;

Výsledkem je velmi krátké časové okno, kde je tabulka výhradně uzamčena.

Tady jde opravdu jen o výkon. Poměrně rychle vytvoří nový stůl bez nadýmání. Máte-li cizí klíče nebo pohledy, stále můžete jít touto cestou, ale musíte si připravit skript k odstranění a opětovnému vytvoření těchto objektů, což může potenciálně vytvářet další exkluzivní zámky.

Souběžné zápisy

Se souběžnými operacemi zápisu opravdu vše, co můžete udělat, je rozdělit aktualizaci na kousky. Nemůžete to udělat v jedné transakci, protože zámky se uvolní až na konci transakce.

Mohli byste používat dblink , který může spouštět nezávislé transakce na jiné databázi, včetně sebe sama. Tímto způsobem byste to mohli udělat vše v jediném DO příkaz nebo funkce plpgsql se smyčkou. Zde je volně související odpověď s dalšími informacemi o dblink:

  • Zrušte nebo vytvořte databázi z uložené procedury v PostgreSQL

Váš přístup pomocí kurzorů

Kurzor uvnitř funkce vám nic nekoupí . Jakákoli funkce je automaticky uzavřena v transakci a všechny zámky se uvolní až na konci transakce. I když jste použili CLOSE cursor (což vy ne) uvolnilo by to pouze některé zdroje, ale ne uvolnit získané zámky na stole. Cituji manuál:

CLOSE zavře portál pod otevřeným kurzorem. Toho lze použít k uvolnění zdrojů před koncem transakce nebo k uvolnění proměnné kurzoru, aby ji bylo možné znovu otevřít.

Budete muset spustit samostatně transakce nebo (ab)použijte dblink, který to udělá za vás.




  1. Jak Now() funguje v PostgreSQL

  2. Vysvětlení funkce zabezpečení serveru SQL HAS_Permis_BY_Name a její případy použití

  3. Hromadné DELETE na SQL Server 2008 (Existuje něco jako Bulk Copy (bcp) pro odstranění dat?)

  4. Jak najít položku seznamu na zadané pozici v SQL Server