Megosztás a következőn keresztül:


Adatok tömörítése oszlopos táblákkal az Azure Cosmos DB for PostgreSQL-ben

Fontos

Az Azure Cosmos DB for PostgreSQL már nem támogatott új projektek esetén. Ne használja ezt a szolgáltatást új projektekhez. Ehelyett használja az alábbi két szolgáltatás egyikét:

  • Az Azure Cosmos DB for NoSQL használata nagy léptékű forgatókönyvekhez tervezett elosztott adatbázis-megoldáshoz 99,999% rendelkezésre állási szolgáltatásiszint-szerződéssel (SLA), azonnali automatikus skálázással és automatikus feladatátvétellel több régióban.

  • Használja az Azure Database For PostgreSQL Rugalmas fürtök funkcióját a megosztott PostgreSQL-hez a nyílt forráskódú Citus-bővítmény használatával.

Az Azure Cosmos DB for PostgreSQL támogatja a csak hozzáfűzést engedélyező oszlopos táblatárolást elemzési és adattárházi munkaterhelésekhez. Ha az oszlopok (sorok helyett) egy helyen vannak tárolva a lemezen, az adatok tömöríthetőbbé válnak, és a lekérdezések gyorsabban kérhetik az oszlopok egy részhalmazát.

Tábla létrehozása

Oszlopos tárolás használatához adja meg USING columnar a tábla létrehozásakor:

CREATE TABLE contestant (
    handle TEXT,
    birthdate DATE,
    rating INT,
    percentile FLOAT,
    country CHAR(3),
    achievements TEXT[]
) USING columnar;

Az Azure Cosmos DB for PostgreSQL a beszúrás során "csíkokban" oszlopos tárolóvá alakítja a sorokat. Minden sáv egy tranzakció adatértékét vagy 150 000 sort tartalmaz, attól függően, hogy melyik a kisebb. (Az oszlopos tábla csíkmérete és egyéb paraméterei a alter_columnar_table_set függvénnyel módosíthatók.)

Az alábbi utasítás például mind az öt sort ugyanabba a sávba helyezi, mivel az összes érték egyetlen tranzakcióba van beszúrva:

-- insert these values into a single columnar stripe

INSERT INTO contestant VALUES
  ('a','1990-01-10',2090,97.1,'XA','{a}'),
  ('b','1990-11-01',2203,98.1,'XA','{a,b}'),
  ('c','1988-11-01',2907,99.4,'XB','{w,y}'),
  ('d','1985-05-05',2314,98.3,'XB','{}'),
  ('e','1995-05-05',2236,98.2,'XC','{a}');

Ha lehetséges, érdemes nagy csíkokat készíteni, mert az Azure Cosmos DB for PostgreSQL csíkonként külön tömöríti az oszlopos adatokat. Az oszlopos táblázattal kapcsolatos tényeket láthatjuk, például a tömörítési arányt, a csíkok számát és a sávonkénti átlagos sorokat a következő használatával VACUUM VERBOSE:

VACUUM VERBOSE contestant;
INFO:  statistics for "contestant":
storage id: 10000000000
total file size: 24576, total data size: 248
compression rate: 1.31x
total row count: 5, stripe count: 1, average rows per stripe: 5
chunk count: 6, containing data for dropped columns: 0, zstd compressed: 6

A kimenet azt mutatja, hogy az Azure Cosmos DB for PostgreSQL a zstd tömörítési algoritmussal szerezte be az 1,31-szeres adattömörítést. A tömörítési sebesség összehasonlítja a) a beszúrt adatok méretét a memóriában a b) a végleges sávban tömörített adatok méretével.

A mérés módjától függően a tömörítési arány változhat, és nem feltétlenül egyezik meg a tábla sor- és oszloptárolása közötti méretkülönbséggel. A különbséget csak úgy lehet igazán megtalálni, ha egy olyan sor- és oszloptáblát hoz létre, amely ugyanazokat az adatokat tartalmazza, és összehasonlítja azokat.

Tömörítés mérése

Hozzunk létre egy új példát több adattal a tömörítési megtakarítások összehasonlításához.

-- first a wide table using row storage
CREATE TABLE perf_row(
  c00 int8, c01 int8, c02 int8, c03 int8, c04 int8, c05 int8, c06 int8, c07 int8, c08 int8, c09 int8,
  c10 int8, c11 int8, c12 int8, c13 int8, c14 int8, c15 int8, c16 int8, c17 int8, c18 int8, c19 int8,
  c20 int8, c21 int8, c22 int8, c23 int8, c24 int8, c25 int8, c26 int8, c27 int8, c28 int8, c29 int8,
  c30 int8, c31 int8, c32 int8, c33 int8, c34 int8, c35 int8, c36 int8, c37 int8, c38 int8, c39 int8,
  c40 int8, c41 int8, c42 int8, c43 int8, c44 int8, c45 int8, c46 int8, c47 int8, c48 int8, c49 int8,
  c50 int8, c51 int8, c52 int8, c53 int8, c54 int8, c55 int8, c56 int8, c57 int8, c58 int8, c59 int8,
  c60 int8, c61 int8, c62 int8, c63 int8, c64 int8, c65 int8, c66 int8, c67 int8, c68 int8, c69 int8,
  c70 int8, c71 int8, c72 int8, c73 int8, c74 int8, c75 int8, c76 int8, c77 int8, c78 int8, c79 int8,
  c80 int8, c81 int8, c82 int8, c83 int8, c84 int8, c85 int8, c86 int8, c87 int8, c88 int8, c89 int8,
  c90 int8, c91 int8, c92 int8, c93 int8, c94 int8, c95 int8, c96 int8, c97 int8, c98 int8, c99 int8
);

-- next a table with identical columns using columnar storage
CREATE TABLE perf_columnar(LIKE perf_row) USING COLUMNAR;

Töltse ki mindkét táblát ugyanazzal a nagy adatkészlettel:

INSERT INTO perf_row
  SELECT
    g % 00500, g % 01000, g % 01500, g % 02000, g % 02500, g % 03000, g % 03500, g % 04000, g % 04500, g % 05000,
    g % 05500, g % 06000, g % 06500, g % 07000, g % 07500, g % 08000, g % 08500, g % 09000, g % 09500, g % 10000,
    g % 10500, g % 11000, g % 11500, g % 12000, g % 12500, g % 13000, g % 13500, g % 14000, g % 14500, g % 15000,
    g % 15500, g % 16000, g % 16500, g % 17000, g % 17500, g % 18000, g % 18500, g % 19000, g % 19500, g % 20000,
    g % 20500, g % 21000, g % 21500, g % 22000, g % 22500, g % 23000, g % 23500, g % 24000, g % 24500, g % 25000,
    g % 25500, g % 26000, g % 26500, g % 27000, g % 27500, g % 28000, g % 28500, g % 29000, g % 29500, g % 30000,
    g % 30500, g % 31000, g % 31500, g % 32000, g % 32500, g % 33000, g % 33500, g % 34000, g % 34500, g % 35000,
    g % 35500, g % 36000, g % 36500, g % 37000, g % 37500, g % 38000, g % 38500, g % 39000, g % 39500, g % 40000,
    g % 40500, g % 41000, g % 41500, g % 42000, g % 42500, g % 43000, g % 43500, g % 44000, g % 44500, g % 45000,
    g % 45500, g % 46000, g % 46500, g % 47000, g % 47500, g % 48000, g % 48500, g % 49000, g % 49500, g % 50000
  FROM generate_series(1,50000000) g;

INSERT INTO perf_columnar
  SELECT
    g % 00500, g % 01000, g % 01500, g % 02000, g % 02500, g % 03000, g % 03500, g % 04000, g % 04500, g % 05000,
    g % 05500, g % 06000, g % 06500, g % 07000, g % 07500, g % 08000, g % 08500, g % 09000, g % 09500, g % 10000,
    g % 10500, g % 11000, g % 11500, g % 12000, g % 12500, g % 13000, g % 13500, g % 14000, g % 14500, g % 15000,
    g % 15500, g % 16000, g % 16500, g % 17000, g % 17500, g % 18000, g % 18500, g % 19000, g % 19500, g % 20000,
    g % 20500, g % 21000, g % 21500, g % 22000, g % 22500, g % 23000, g % 23500, g % 24000, g % 24500, g % 25000,
    g % 25500, g % 26000, g % 26500, g % 27000, g % 27500, g % 28000, g % 28500, g % 29000, g % 29500, g % 30000,
    g % 30500, g % 31000, g % 31500, g % 32000, g % 32500, g % 33000, g % 33500, g % 34000, g % 34500, g % 35000,
    g % 35500, g % 36000, g % 36500, g % 37000, g % 37500, g % 38000, g % 38500, g % 39000, g % 39500, g % 40000,
    g % 40500, g % 41000, g % 41500, g % 42000, g % 42500, g % 43000, g % 43500, g % 44000, g % 44500, g % 45000,
    g % 45500, g % 46000, g % 46500, g % 47000, g % 47500, g % 48000, g % 48500, g % 49000, g % 49500, g % 50000
  FROM generate_series(1,50000000) g;

VACUUM (FREEZE, ANALYZE) perf_row;
VACUUM (FREEZE, ANALYZE) perf_columnar;

Ezen adatok esetében az oszlopos táblázatban 8X-nél jobb tömörítési arány látható.

SELECT pg_total_relation_size('perf_row')::numeric/
       pg_total_relation_size('perf_columnar') AS compression_ratio;
 compression_ratio
--------------------
 8.0196135873627944
(1 row)

Példa

Az oszlopos tárolás jól működik a táblaparticionálással. Például tekintse meg a Citus Engine közösségi dokumentációját, amely oszlopos tárolóval archivál.

Buktatók

  • Az oszlopos tárolás csíkonként tömörít. A sávok tranzakciónként jönnek létre, így tranzakciónként egy sor beszúrása egyetlen sort helyez el a saját sávjaikban. Az egysoros csíkok tömörítése és teljesítménye rosszabb lesz, mint egy sortábla. Mindig csoportosan helyezzen be oszlop-szerkezetű táblázatba.
  • Ha elrontasz valamit, és oszlopokká alakítasz egy csomó apró csíkot, elakadsz. Az egyetlen javítás egy új oszlopos tábla létrehozása és az adatok másolása az eredetiből egy tranzakcióban:
    BEGIN;
    CREATE TABLE foo_compacted (LIKE foo) USING columnar;
    INSERT INTO foo_compacted SELECT * FROM foo;
    DROP TABLE foo;
    ALTER TABLE foo_compacted RENAME TO foo;
    COMMIT;
    
  • A nem tömöríthető adatok alapvetően problémát jelenthetnek, bár az oszlopos tárolás még mindig hasznos adott oszlopok kiválasztásakor. Nem kell betöltenie a többi oszlopot a memóriába.
  • A sor- és oszloppartíciók keverékével rendelkező particionált táblákon a frissítéseket gondosan meg kell célozni. Szűrje őket úgy, hogy csak a sorpartíciókat érje el.
    • Ha a művelet egy adott sorpartícióra (például UPDATE p2 SET i = i + 1), akkor sikeres lesz; ha egy adott oszlopos partícióra van megcélzva (például UPDATE p1 SET i = i + 1), az sikertelen lesz.
    • Ha a művelet a particionált táblára irányul, és rendelkezik egy WHERE záradékkal, amely kizárja az összes oszlopos partíciót (például UPDATE parent SET i = i + 1 WHERE timestamp = '2020-03-15'), akkor az sikeres lesz.
    • Ha a művelet a particionált táblára irányul, de nem szűr a partíciókulcs oszlopaira, az sikertelen lesz. Még ha vannak olyan WHERE záradékok is, amelyek csak az oszlopos partíciók soraival egyeznek meg, az sem elég – a partíciókulcsot is szűrni kell.

Korlátozások

Ez a funkció továbbra is jelentős korlátozásokkal rendelkezik:

  • A tömörítés a lemezen van, nem a memóriában
  • Csak hozzáfűzés (nincs frissítési/törlési támogatás)
  • Nincs lemezterület-visszanyerés (például a visszagördített tranzakciók továbbra is foglalhatnak lemezterületet)
  • Nincs indextámogatás, indexvizsgálat vagy bitképindex-vizsgálat
  • Nincs tidscans
  • Nincs mintavizsgálat
  • Nincs TOAST-támogatás (nagy értékek beágyazottan támogatva)
  • Az ON CONFLICT utasítások nem támogatottak (kivéve a DO NOTHING műveleteket, amelyekhez nincs megadva cél).
  • Nincs támogatás a tuple zárakhoz (SELECT ... FOR SHARE, SELECT ... FOR UPDATE)
  • A szerializálható elkülönítési szint nem támogatott
  • Csak a PostgreSQL-kiszolgáló 12+-os verzióinak támogatása
  • Nem támogatottak a külső kulcsok, az egyedi korlátozások vagy a kizárási korlátozások
  • A logikai dekódolás nem támogatott
  • A csomóponton belüli párhuzamos vizsgálatok nem támogatottak
  • Nincs támogatás a AFTER ... MINDEN SOR-eseményindítóhoz
  • Nincsenek naplózatlan oszlopos táblázatok
  • Nincsenek IDEIGLENES oszloptáblák

Következő lépések

  • Tekintse meg az oszlopos tárolás példáját egy Citus-idősor oktatóanyagában (külső hivatkozás).