PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Obliczanie i oszczędzanie miejsca w PostgreSQL

"Kolumnowy Tetris"

Właściwie możesz coś zrobić , ale wymaga to głębszego zrozumienia. Słowo kluczowe to wypełnienie wyrównania . Każdy typ danych ma określone wymagania dotyczące wyrównania.

Możesz zminimalizować miejsce tracone na wypełnienie między kolumnami zamawiając je korzystnie. Poniższy (ekstremalny) przykład zmarnowałby dużo miejsca na dysku fizycznym:

CREATE TABLE t (
    e int2    -- 6 bytes of padding after int2
  , a int8
  , f int2    -- 6 bytes of padding after int2
  , b int8
  , g int2    -- 6 bytes of padding after int2
  , c int8
  , h int2    -- 6 bytes of padding after int2
  , d int8)

Aby zaoszczędzić 24 bajty na wiersz, użyj zamiast tego:

CREATE TABLE t (
    a int8
  , b int8
  , c int8
  , d int8
  , e int2
  , f int2
  , g int2
  , h int2)   -- 4 int2 occupy 8 byte (MAXALIGN), no padding at the end

db<>graj tutaj
Stary sqlfiddle

Zgodnie z ogólną zasadą, jeśli najpierw umieścisz kolumny 8-bajtowe, a następnie kolumny 4-bajtowe, 2-bajtowe i 1-bajtowe, nie możesz się pomylić.

boolean , uuid (!) i kilka innych typów nie wymaga dopełnienia wyrównania. text , varchar i inne typy „varlena” (o zmiennej długości) nominalnie wymagają wyrównania "int" (4 bajty na większości maszyn). Ale nie zaobserwowałem dopełnienia wyrównania w formacie dysku (w przeciwieństwie do pamięci RAM). W końcu znalazłem wyjaśnienie w notatce w kodzie źródłowym:

Zauważ również, że pozwalamy na naruszenie nominalnego wyrównania podczas przechowywania „zapakowanych” varlenas; mechanizm TOAST zajmuje się ukrywaniem tego przed większością kodu.

Tak więc wyrównanie "int" jest wymuszane tylko wtedy, gdy (prawdopodobnie skompresowane) dane zawierające jeden bajt długości wiodącej przekracza 127 bajtów. Następnie pamięć varlena przełącza się na cztery wiodące bajty i wymaga wyrównania „int”.

Zwykle możesz zapisać kilka bajtów w wierszu, najlepiej grając w "kolumnę tetris" . W większości przypadków nie jest to konieczne. Ale przy miliardach wierszy może to łatwo oznaczać kilka gigabajtów.

Możesz przetestować rzeczywisty rozmiar kolumny / wiersza za pomocą funkcji pg_column_size() .
Niektóre typy zajmują więcej miejsca w pamięci RAM niż na dysku (format skompresowany lub „spakowany”). Możesz uzyskać większe wyniki dla stałych (format RAM) niż dla kolumn tabeli podczas testowania tej samej wartości (lub wiersza wartości w porównaniu z wierszem tabeli) za pomocą pg_column_size() .

Wreszcie, niektóre typy mogą być skompresowane lub „tosty” (przechowywane poza linią) lub jedno i drugie.

Narzut na krotkę (wiersz)

4 bajty na wiersz dla identyfikatora pozycji - nie podlega powyższym rozważaniom.
I co najmniej 24 bajty (23 + dopełnienie) dla nagłówka krotki. Instrukcja dotycząca układu strony bazy danych:

Istnieje nagłówek o stałym rozmiarze (zajmujący 23 bajty na większości komputerów), po którym następuje opcjonalna bitmapa zerowa, opcjonalne pole identyfikatora obiektu i dane użytkownika.

Aby wypełnić wypełnienie między nagłówkiem a danymi użytkownika, musisz znać MAXALIGN na twoim serwerze - zwykle 8 bajtów w 64-bitowym systemie operacyjnym (lub 4 bajty w 32-bitowym systemie operacyjnym). Jeśli nie jesteś pewien, sprawdź pg_controldata .

Uruchom następujące w swoim katalogu binarnym Postgres aby uzyskać ostateczną odpowiedź:

./pg_controldata /path/to/my/dbcluster

Instrukcja:

Rzeczywiste dane użytkownika (kolumny wiersza) zaczynają się od przesunięcia wskazanego przez t_hoff , który zawsze musi być wielokrotnością MAXALIGN odległość od platformy.

Tak więc zazwyczaj uzyskujesz optymalną pamięć, pakując dane w wielokrotności 8 bajtów.

Nie ma nic do zyskania w opublikowanym przez Ciebie przykładzie . Jest już ciasno zapakowany. 2 bajty dopełnienia po ostatnim int2 , 4 bajty na końcu. Możesz skonsolidować dopełnienie do 6 bajtów na końcu, co niczego by nie zmieniło.

Narzut na stronę danych

Rozmiar strony danych wynosi zwykle 8 KB. Trochę narzutu/rozdęcia również na tym poziomie:pozostałości nie są wystarczająco duże, aby zmieścić kolejną krotkę, a co ważniejsze martwe wiersze lub procent zarezerwowany za pomocą FILLFACTOR ustawienie.

Należy wziąć pod uwagę kilka innych czynników dotyczących rozmiaru dysku:

  • Ile rekordów mogę przechowywać w 5 MB PostgreSQL w Heroku?
  • Czy nie używasz NULL w PostgreSQL nadal używa bitmapy NULL w nagłówku?
  • Konfigurowanie PostgreSQL pod kątem wydajności odczytu

Typy tablic?

Z tablicą wpisz tak, jak oceniasz, dodałbyś 24 bajty narzutu dla typu. Ponadto elementy tablicy zajmują miejsce jak zwykle. Nie ma tam nic do zyskania.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. 8 nowych funkcji zgodności z Oracle w EnterpriseDB PPAS 9.2 Beta

  2. Dynamiczne zapytanie przestawne przy użyciu PostgreSQL 9.3

  3. Zresetuj klucz podstawowy PostgreSQL do 1

  4. Zmień kodowanie bazy danych PostgreSql

  5. Jak zmienić kolumnę PG na NULLABLE TRUE?