AnalyticDB PostgreSQL支持多種存儲格式。當您創建一個表時,可以選擇表的存儲格式為行存表或者列存表。

行存表

默認情況下,AnalyticDB PostgreSQL創建的是行存表。行存表使用和 PostgreSQL 相同的堆存儲模型(Heap Table),在 OLTP 類型負載下表現最好:這種場景中,數據常由每次一行或幾行的 INSERT 實時插入,且在初始插入后可能被頻繁地修改或刪除。如有較小的表(例如維度表),建議選擇行存表。同時,當行存表建有于B-Tree索引時,具備更好的點查詢數據檢索性能。

說明 當采用數據傳輸服務DTS寫入AnalyticDB PostgreSQL時,AnalyticDB PostgreSQL的目標表建議設計為行存表,而不要采用列存表。DTS為準實時數據同步的方式,除INSERT外,同時支持UPDATE和DELETE等較多更新操作的同步。

下述語句創建了一個默認堆存儲類型的行存表 foo。

CREATE TABLE foo (a int, b text)
DISTRIBUTED BY (a);

列存表

列存表(Column-Oriented Table)的按列存儲格式,數據訪問只會讀取涉及的列,適合少量列的數據查詢、聚集等數據倉庫應用場景,在此類場景中,列存表能夠提供更高效的 I/O。但列存表不適合頻繁的更新操作或者大批量的INSERT寫入場景,這時其效率較低。列存表的數據寫入建議采用 COPY 等批量加載方式。列存表可以提供平均 3~5倍的較高數據壓縮率。

列存表必須是追加優化表,即要創建一個列存表,必須指定為 "appendonly=true"。

下述語句創建了一個列存表bar。

CREATE TABLE bar (a int, b text)
WITH (appendonly=true, orientation=column)
DISTRIBUTED BY (a);

選擇面向行或者面向列的存儲

行存表和列存表的選擇需根據實際負載而定,在為一個表決定存儲格式時,建議參考下列需求:

  • 對于大部分常用目的或者混合負載,行存表兼顧了靈活性和性能。
  • 如果會頻繁地一條或幾條地插入數據、已有數據會被頻繁的修改和刪除,請考慮行存表。
  • 如果基本是大批量地導入數據,且已有數據很少被修改和刪除,請考慮列存表。
  • 如果查詢的投影列表或者條件語句中常常要求所有或者大部分列,或者表的行尺寸相對較小時,請考慮行存表;相反,如果表具有很多列,且查詢常常訪問這些列的一個小子集時,請考慮列存表。
  • 空間占用考慮:列存表中的每一列具有相同的數據類型,便于使用臨近數據的相似性來進行壓縮,因此在空間占用上比行存表更有優勢;另一方面,壓縮做得越好,隨機訪問就會越困難。

修改表的存儲格式

表存儲格式(行存或列存)只能在創建表時聲明。要改變存儲模型,必須使用目標的存儲格式創建一個表,將原始表的數據載入到新表中,刪除原始表,并把新表重命名為原始表的名稱。用戶還必須重新授權原始表上有的權限。注意這個過程不是原子的,為保證數據完整性,需要業務側保證在修改的過程中對原始表只讀。

將行存表foo重新載入為列存表。

CREATE TABLE foo_tmp (LIKE foo) WITH (appendonly=true, orientation=column);
INSERT INTO foo_tmp SELECT * FROM sales;
DROP TABLE foo;
ALTER TABLE foo_tmp RENAME TO foo;

GRANT ALL PRIVILEGES ON foo TO user1;
GRANT SELECT ON foo TO user2;