2012-11-09 10 views
7

Sto cercando di ottenere le dimensioni della tabella anticipate facendo riferimento al tipo di colonna e alla lunghezza. Sto cercando di usare pg_column_size per questo.Come può pg_column_size essere minore di octet_length?

Durante il test della funzione, ho realizzato che qualcosa sembra sbagliato in questa funzione.

Il valore del risultato da pg_column_size(...) è talvolta inferiore al valore di ritorno da octet_length(...) sulla stessa stringa.

Nella colonna non sono presenti caratteri numerici.

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) 

È questo l'errore o qualcosa del genere? C'è qualcuno con la formula per calcolare le dimensioni della tabella anticipate da tipi di colonna e valori di lunghezza?

risposta

12

direi pg_column_size sta riportando la dimensione compressa di TOAST valori di ED, mentre octet_length sta riportando i formati non compressi. Non ho verificato ciò verificando la funzione source o le definizioni, ma avrebbe avuto senso, specialmente se le stringhe di numeri si comprimevano abbastanza bene. Stai utilizzando la memoria EXTENDED in modo che i valori siano idonei per la compressione TOAST. Vedi the TOAST documentation.

Come per il calcolo delle dimensioni del DB previsto, è tutta una nuova domanda. Come puoi vedere dalla seguente demo, dipende da quanto sono compressibili le tue stringhe.

Ecco una dimostrazione mostrando come octet_length può essere più grande di pg_column_size, dimostrando dove calci brindisi in primo luogo, prendiamo i risultati sul risultato di una query in cui nessuno TOAST entra in gioco:.

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) 

Ora andiamo negozio che lo stesso interrogare l'output in una tabella e ottenere la dimensione delle righe memorizzate:

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

Grazie mille ... – KIM

Problemi correlati