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

Reprezentace řídkých dat v PostgreSQL

Předpokládám, že máte na mysli řídké matice z matematického kontextu:http://en.wikipedia. org/wiki/Sparse_matrix (Tam popsané techniky ukládání jsou pro ukládání do paměti (rychlá aritmetická operace), nikoli pro trvalé ukládání (nízké využití disku).)

Vzhledem k tomu, že se obvykle pracuje s touto matricí na straně klienta spíše než na straně serveru, je SQL-ARRAY[] nejlepší volbou!

Otázkou je, jak využít řídkost matice? Zde jsou výsledky některých vyšetřování.

Nastavení:

  • Postgres 8.4
  • Matice s 400*400 prvky s dvojnásobnou přesností (8 bajtů) --> 1,28 MiB hrubá velikost na matici
  • 33 % nenulových prvků --> 427 kB efektivní velikost na matici
  • zprůměrováno pomocí ~1000 různých náhodně vyplněných matic

Soutěžní metody:

  • Spolehněte se na automatické komprese na straně serveru sloupců s SET STORAGE MAIN nebo EXTENDED.
  • Ukládejte pouze nenulové prvky plus bitmapu (bit varying(xx) ) popisující, kde v matici umístit nenulové prvky. (Jedna dvojnásobná přesnost je 64krát větší než jeden bit. Teoreticky (bez ohledu na režii) by tato metoda měla být zlepšením, pokud <=98 % je nenulových;-).) Je aktivována komprese na straně serveru.
  • Nahradit nuly v matici s NULL . (RDBMS jsou velmi účinné při ukládání hodnot NULL.) Je aktivována komprese na straně serveru.

(Indexování nenulových prvků pomocí 2nd index-ARRAY[] není příliš slibné, a proto není testováno.)

Výsledky:

  • Automatická komprese
    • žádné dodatečné implementační úsilí
    • žádný snížený provoz v síti
    • minimální kompresní režie
    • trvalé úložiště =39 % původní velikosti
  • Bitmapa
    • přijatelné úsilí o implementaci
    • síťový provoz se mírně snížil; závislé na řídkosti
    • trvalé úložiště =33,9 % původní velikosti
  • Nuly nahraďte hodnotami NULL
    • nějaké implementační úsilí (API potřebuje vědět, kde a jak nastavit hodnoty NULL v ARRAY[] při vytváření dotazu INSERT)
    • žádná změna síťového provozu
    • trvalé úložiště =35 % původní velikosti

Závěr:Začněte parametrem EXTENDED/MAIN úložiště. Pokud máte nějaký volný čas, prozkoumejte svá data a použijte moje testovací nastavení s vaší úrovní řídkosti. Ale účinek může být nižší, než očekáváte.

Pro rozměry matice NxM doporučuji vždy použít serializaci matice (např. Row-major order) plus dva celočíselné sloupce. Protože většina API používá textové SQL, šetříte spoustu síťového provozu a klientské paměti pro vnořené "ARRAY[ARRAY[..], ARRAY[..], ARRAY[..], ARRAY[..], ..]" !!!

Tebas

CREATE TABLE _testschema.matrix_dense
(
  matdata double precision[]
);
ALTER TABLE _testschema.matrix_dense ALTER COLUMN matdata SET STORAGE EXTERN;


CREATE TABLE _testschema.matrix_sparse_autocompressed
(
  matdata double precision[]
);

CREATE TABLE _testschema.matrix_sparse_bitmap
(
  matdata double precision[]
  bitmap bit varying(8000000)
);

Vložte stejné matice do všech tabulek. Konkrétní data závisí na konkrétní tabulce. Neměňte data na straně serveru kvůli nevyužitým, ale přiděleným stránkám. Nebo udělejte VAKUUM.

SELECT 
pg_total_relation_size('_testschema.matrix_dense') AS dense, 
pg_total_relation_size('_testschema.matrix_sparse_autocompressed') AS autocompressed, 
pg_total_relation_size('_testschema.matrix_sparse_bitmap') AS bitmap;


  1. metoda table_exists() možná nefunguje správně

  2. Jak se připojíte ke stejnému stolu dvakrát v mysql?

  3. Cheat sheet formátu data MySQL

  4. Jak předat sadu řádků z jedné funkce do druhé?