Postgresql

DB中的數據大小遠大於轉儲到磁碟的數據大小

  • December 14, 2021

我有一個表,其中包含數據庫中 99.9% 的數據。當我查詢表和數據庫的大小時,我得到:

mydb=# SELECT pg_size_pretty( pg_database_size('mydb') );
pg_size_pretty 
----------------
169 GB
(1 row)

mydb=# SELECT pg_size_pretty( pg_total_relation_size('data.my_table') );
pg_size_pretty 
----------------
169 GB
(1 row)

我使用腳本將所有數據作為 csvs 轉儲到磁碟。腳本是一系列語句,每個項目一個。例如,對於項目 1825,我執行了以下查詢。

\copy ( select o.period, s.name as symbol, s.text  from data.my_table o join data.symbol s on s.id = o.symbol_id where s.id = 1825 and o.period >= 1577836800000 and o.period < 1609459200000 ) to '/media/user/hdd1/db_dump/2020/symbol_1825.csv' CSV HEADER; 

將所有數據作為 CSV 轉儲到磁碟後,CSV 的總大小小於 psql 報告的數據庫大小。我是否應該期望數據庫的大小與轉儲到磁碟上的文件的大小大致相同(在幾 GB 內),或者這是一個錯誤的假設?

該表非常簡單——沒有定義索引,只是一個主鍵。

您的查詢僅轉儲 3 列。但是您在數據庫中至少還有兩列沒有被轉儲(連接條件中使用的列)。如果 o.period 上的條件沒有刪除任何行,那麼為什麼還要麻煩呢?

PostgreSQL 的每一行有大約 30 字節的成本。另外,您有一個索引(它自動與主鍵一起提供),它具有更多的每行成本。你的行看起來很瘦,所以這個成本將構成數據庫的很大一部分。

pg_total_relation_size()不是最好的開始。手冊:

計算指定表使用的總磁碟空間,包括所有索引和 TOAST 數據。結果等價於pg_table_size+ pg_indexes_size

pg_table_size('data.my_table')

計算指定表使用的磁碟空間,不包括索引(但包括其 TOAST 表(如果有)、可用空間映射和可見性映射)。

如果沒有使用 TOAST 表,則最佳近似值是**pg_relation_size('data.my_table')**

別的:

 pg_table_size('data.my_table')
- pg_relation_size('data.my_table', 'vm')
- pg_relation_size('data.my_table', 'fsm')

當然,要與包含相同表格的 CSV 文件進行比較。然而,將您的查詢結果與任何東西進行比較要困難得多。

但是,所有這些只是一個非常粗略的近似,因為 Postgres 儲存比 CSV 文件中的文本表示要復雜得多。對於大多數短字元串,數字將接近。但是 CSV 文件可以小得多或大得多,具體取決於廣泛的細節。最重要的是,大字元串在 TOAST 表中被壓縮,並且 (OTOH) 死元組和其他膨脹不包含在 CSV 文件中。看:

引用自:https://dba.stackexchange.com/questions/303938