2012-11-09 14 views
7

Poszukuję przewidywanego rozmiaru tabeli, określając typ kolumny i jej długość. Próbuję użyć do tego celu pg_column_size.W jaki sposób pg_column_size może być mniejsza niż długość oktet_length?

Podczas testowania funkcji zdałem sobie sprawę, że z tą funkcją wydaje się być nie tak.

Wartość wyniku z pg_column_size(...) jest czasami nawet mniejsza niż wartość zwracana z octet_length(...) na tym samym ciągu.

W kolumnie znajdują się tylko cyfry.

postgres=# \d+ t5 
          Table "public.t5" 
Column |  Type  | Modifiers | Storage | Stats target | Description 
--------+-------------------+-----------+----------+--------------+------------- 
c1  | character varying |   | extended |    | 
Has OIDs: no 

postgres=# select pg_column_size(c1), octet_length(c1) as octet from t5; 
pg_column_size | octet 
----------------+------- 
       2 |  1 
      704 | 700 
      101 | 7000 
      903 | 77000 
(4 rows) 

Czy to błąd? Czy istnieje ktoś z pewnym wzorem do obliczenia przewidywanego rozmiaru tabeli z typów kolumn i ich długości?

Odpowiedz

12

Powiedziałbym, że pg_column_size zgłasza skompresowany rozmiar wartości TOAST ed, a octet_length zgłasza nieskompresowane rozmiary. Nie zweryfikowałem tego, sprawdzając źródło funkcji lub definicje, ale miałoby to sens, zwłaszcza że ciągi liczb będą kompresować całkiem dobrze. Używasz pamięci masowej EXTENDED, więc wartości kwalifikują się do kompresji TOAST. Zobacz the TOAST documentation.

Jeśli chodzi o obliczanie oczekiwanego rozmiaru bazy danych, to jest to nowe pytanie. Jak widać z poniższej wersji demo, zależy to od tego, jak ściśliwe są twoje struny.

Oto demonstracja pokazuje jak octet_length może być większa niż pg_column_size, wykazując miarę kopnięć toast Najpierw przejdźmy wyniki na wyjściu zapytań gdzie nie TOAST wchodzi w grę.

regress=> SELECT octet_length(repeat('1234567890',(2^n)::integer)), pg_column_size(repeat('1234567890',(2^n)::integer)) FROM generate_series(0,12) n; 
octet_length | pg_column_size 
--------------+---------------- 
      10 |    14 
      20 |    24 
      40 |    44 
      80 |    84 
      160 |   164 
      320 |   324 
      640 |   644 
     1280 |   1284 
     2560 |   2564 
     5120 |   5124 
     10240 |   10244 
     20480 |   20484 
     40960 |   40964 
(13 rows) 

Teraz sklepu, który sam dane wyjściowe zapytania do tabeli i uzyskać rozmiar przechowywanych wierszy:

regress=> CREATE TABLE blah AS SELECT repeat('1234567890',(2^n)::integer) AS data FROM generate_series(0,12) n; 
SELECT 13 

regress=> SELECT octet_length(data), pg_column_size(data) FROM blah; 
octet_length | pg_column_size 
--------------+---------------- 
      10 |    11 
      20 |    21 
      40 |    41 
      80 |    81 
      160 |   164 
      320 |   324 
      640 |   644 
     1280 |   1284 
     2560 |    51 
     5120 |    79 
     10240 |   138 
     20480 |   254 
     40960 |   488 
(13 rows) 
+0

Dziękuję bardzo ... – KIM

Powiązane problemy