PostgreSQL:分離表與單表以保持磁碟空間?
我有 2 個具有以下模式的表,它們的行數相同。當我執行
SELECT relname, relpages FROM pg_class ORDER BY relpages DESC
命令時,即使這兩個模式的數據類型(總字節數)導致不同的大小,它們每個顯示為 23GB。確定通過組合表格可以節省多少空間的最佳方法是什麼?另外,有什麼方法可以確定每行實際佔用多少空間?Table "public.table1" Column | Type | Modifiers --------------+--------------------------+----------------------------------------------------- field1 | smallint | field2 | smallint | field3 | integer | field4 | smallint | timestamp | timestamp with time zone | user_id | integer | status | boolean | id | integer | not null default Table "public.table2" Column | Type | Modifiers ----------------+--------------------------+---------------------------------------------------- user_id | integer | begin_timestamp | timestamp with time zone | end_timestamp | timestamp with time zone | field | smallint | not null id | integer | not null default
恕我直言,一個合理的答案必須問(或至少暗示)這個問題:為什麼桌子一開始就分開了?(更重要的是:它仍然適用嗎?)
一般情況: 我不知道postgres db引擎如何工作的細節,但是節省的磁碟空間的下限可能不大於刪除的列的大小+重複變數的索引+一些管家數據
上限也很小,因此可能不值得麻煩;甚至可能出於性能原因對它們進行了分區-因為某些列會被更頻繁地訪問(讀取,甚至更新),因此可以將其做得更小(更少的列)以使其更快。(同時從兩者訪問列會受到一些懲罰。)
具體情況: 看起來它們之間有很多冗餘欄位。例如,user_id 不需要出現兩次。begin/end/X 時間戳可能會減少到兩個或一個。因此,根據應用程序的要求,可能會有所節省。再一次,試著弄清楚他們為什麼這樣做。
不過,總的來說,我同意 Bryan Agee 的觀點。磁碟空間可能不應該是您開始關注足以執行 postgres 的任何東西。特別是如果您為“修復”此問題所花費的時間獲得報酬,那麼該成本可能會超過更大磁碟本身的成本。
每行空間: 我不精通 postgres 細節,所以知道的人應該能夠糾正任何錯誤。例如有辦法詢問 postgres 特定行實際佔用了多少空間;我一個都不知道。我所寫的基本上是(我相信)今天通常所做的數據庫儲存背後的理論。
每個欄位都有一個位(在它自己的一個字節中,或者在整行通用的位集中),它表示該值是否為空。如果它是一個空值,則沒有更多的儲存。然後是一個長度字節——除非這是從固定寬度數據類型隱含的。然後是數據本身。
因此,一行一個 int(甚至是 64 位)和三個空值可能只需要 3 個字節。(對於 <127 的值,儲存 size=1 和字節。)加上索引和各種其他內務元數據。同樣,我不知道 postgres 在這方面能走多遠。而這些因素加在一起,往往會使“這一行佔多少”成為一個無用答案的問題。
AFAIK postgres 還使用“頁面”操作 - 行可能不會跨邊界儲存的空間塊。因此,較大的記錄可能更多地最終“不適合”頁面,因此需要放置在另一個/新頁面中。