2012-11-09 14 views
7

Ich bin auf der Suche nach der erwarteten Tabellengröße durch Verweis auf Spalte Typ und Länge Größe. Ich versuche pg_column_size dafür zu verwenden.Wie kann pg_column_size kleiner als octet_length sein?

Beim Testen der Funktion wurde mir klar, dass bei dieser Funktion etwas nicht stimmt. Der Ergebniswert von pg_column_size(...) ist manchmal sogar kleiner als der Rückgabewert von octet_length(...) auf derselben Zeichenkette.

In der Spalte befinden sich nur numerische Zeichen.

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) 

Ist das der Fehler oder so? Gibt es jemanden mit der Formel, um die voraussichtliche Tabellengröße aus den Spaltentypen und Längenwerten zu berechnen?

Antwort

12

Ich würde sagen, pg_column_size meldet die komprimierte Größe von TOAST Ed-Werte, während octet_length meldet die unkomprimierten Größen. Ich habe dies nicht überprüft, indem ich die Funktionsquelle oder die Definitionen überprüft habe, aber es wäre sinnvoll, besonders wenn Zahlenfolgen ziemlich gut komprimiert werden. Sie verwenden EXTENDED Speicher, sodass die Werte für TOAST Komprimierung geeignet sind. Siehe the TOAST documentation.

Wie zur Berechnung der erwarteten DB-Größe, das ist ganz neue Frage. Wie Sie in der folgenden Demo sehen können, hängt es zum Beispiel davon ab, wie komprimierbar Ihre Strings sind.

Hier ist eine Demonstration zeigt, wie octet_length größer als pg_column_size sein kann, in denen TOAST Tritte demonstriert Lassen Sie sich zunächst die Ergebnisse auf Abfrageausgabe erhalten, wo keine TOAST ins Spiel kommt.

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) 

Jetzt Store lassen, dass gleiche Ausgabe in eine Tabelle abfragen und die Größe der gespeicherten Zeilen ermitteln:

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

Vielen Dank ... – KIM

Verwandte Themen