2017-08-07 44 views
1

我有一張3327 MB的表格,大約35列。大多數列是布爾值或外鍵id引用。我試圖理解的部分是爲什麼大多數布爾型索引佔用了1091MB和外鍵id(int)1090MB。爲什麼布爾和外鍵id索引是整個表大小的1/3?

+1

由於布爾列具有低基數字段,因此具有布爾上的索引首先不是一個好主意。相反,您可能需要使用[部分索引](https://www.postgresql.org/docs/current/static/indexes-partial.html)。外鍵索引的大小實際上取決於您在給定表中存儲了多少個唯一ID,並且很容易就是您看到的大小。 –

+1

另外,正如你所說的,你的35個列中的大部分都是布爾值。布爾存儲需要1個字節,而整數需要4個字節。所以,你可以用你有多少行以及這些ID列的整體數量多少來簡單計算你的表的存儲量。但是,我看到atm,如果你的描述是真實的,那麼這是完全正常的結果:) –

+0

原來這真是糟糕透頂。在冒犯性表上運行pg_repack會導致數據庫54%和索引73%。感謝每個人的評論。 – CrashRoX

回答

0

我試圖理解的部分是爲什麼大多數布爾型索引佔用了1091MB和外鍵id(int)1090MB。

索引至少總是8個字節。這意味着即使你只是索引一個布爾值,你也浪費了7個字節的存儲空間。

CREATE TABLE foo 
AS 
    SELECT true AS bar, 42 AS baz 
    FROM generate_series(1,1e6); 

CREATE INDEX ON foo(bar); 
CREATE INDEX ON foo(baz); 
CREATE INDEX ON foo(bar,baz); 

test=# \d+ foo; 
         Table "public.foo" 
Column | Type | Modifiers | Storage | Stats target | Description 
--------+---------+-----------+---------+--------------+------------- 
bar | boolean |   | plain |    | 
baz | integer |   | plain |    | 
Indexes: 
    "foo_bar_baz_idx" btree (bar, baz) 
    "foo_bar_idx" btree (bar) 
    "foo_baz_idx" btree (baz) 

test=# \di+ foo; 
No matching relations found. 
test=# \di+ foo* 
          List of relations 
Schema |  Name  | Type | Owner | Table | Size | Description 
--------+-----------------+-------+----------+-------+-------+------------- 
public | foo_bar_baz_idx | index | ecarroll | foo | 21 MB | 
public | foo_bar_idx  | index | ecarroll | foo | 21 MB | 
public | foo_baz_idx  | index | ecarroll | foo | 21 MB | 
public | food_pkey  | index | ecarroll | food | 16 kB | 
(4 rows)