AnalyticDB PostgreSQL版支持列存儲格式,具有較高的數據壓縮能力,以及查詢性能,但是當針對有較高過濾率的查詢條件時,依然要做整列數據讀取,或者建B-Tree索引,但是索引也有其的問題:一是列存表的索引無壓縮,數據膨脹比較嚴重;二是結果集大的時候,索引代價比順序掃描高,索引失效等問題。為此AnalyticDB PostgreSQL版針對此問題開發了MetaScan功能,具有很好的過濾性能,并且占用的存儲空間也基本可以忽略不計。

注意
  • 該特性目前僅支持新建的存儲預留模式實例,且數據庫內核版本為20200826及以后。
  • 如果您的實例是存儲彈性模式實例,請暫時忽略這個特性。

開啟MetaScan功能

MetaScan分為2部分:meta信息收集和MetaScan,由2個系統參數控制開啟和關閉:

  • RDS_ENABLE_CS_ENHANCEMENT

    控制MetaScan的meta信息收集功能,on表示開啟meta信息收集,off表示關閉meta信息收集。系統默認為on,在列存表數據發生變化時,自動收集meta信息。該系統參數是實例級別的參數,如需要修改,可以提工單讓技術支持人員修改。

  • RDS_ENABLE_COLUMN_META_SCAN
    控制查詢是否使用MetaScan,on表示使用MetaScan,off表示不使用MetaScan。系統默認為off。該系統參數為session級別,可以通過下面SQL查看、修改:
    • 查看MetaScan是否開啟
      SHOW RDS_ENABLE_COLUMN_META_SCAN;
    • 關閉MetaScan
      SET RDS_ENABLE_COLUMN_META_SCAN = OFF;
    • 開啟MetaScan
      SET RDS_ENABLE_COLUMN_META_SCAN = ON;
注意 RDS_ENABLE_CS_ENHANCEMENT關閉后,所有列存表都將停止收集meta,如果需要開啟RDS_ENABLE_CS_ENHANCEMENT的話,則在開啟后,要想使用MetaScan功能,必須重新收集表的meta信息,可以使用如下SQL:
ALTER TABLE table_name SET WITH(REORGANIZE=TRUE);

如何查看query是否使用了MetaScan

可以使用EXPLAIN查看SELECT是否使用了MetaScan,如下圖所示:Explain 輸出中的“Append-only Columnar Meta Scan”節點即是MetaScan節點,如果EXPLAIN中有該節點,則表示查詢時使用了MetaScan。

MetaScan支持的類型和操作符

目前版本,MetaScan支持如下數據類型:
  • INT2/INT4/INT8
  • FLOAT4/FLOAT8
  • TIME/TIMETZ/TIMESTAMP/TIMESTAMPTZ
  • VARCHAR/TEXT/BPCHAR
  • CASH
支持如下操作符:
  • =、<、<=、>、>=
  • 邏輯運算符:and

已有實例升級

已有實例要使用MetaScan特性,需要做如下步驟升級AnalyticDB PostgreSQL版版本和表的meta信息:

  1. 升級AnalyticDB PostgreSQL版版本
    從控制臺上點擊小版本升級
  2. 升級表的meta信息

    小版本升級完成后,需要升級表的meta信息到最新版。 如果RDS_ENABLE_CS_ENHANCEMENT是關閉狀態,請提工單聯系技術支持來升級meta信息,否則可以按如下步驟升級表的meta版本:

    1. 使用管理員賬號創建升級函數。
      CREATE OR REPLACE FUNCTION UPGRADE_AOCS_TABLE_META(tname TEXT) RETURNS BOOL AS $$
      DECLARE
          tcount INT := 0;
      BEGIN
          -- CHECK TABLE NAME
          EXECUTE 'SELECT COUNT(1) FROM PG_AOCSMETA WHERE RELID = ''' || tname || '''::REGCLASS' INTO tcount;
          IF tcount IS NOT NULL THEN
              IF tcount > 1 THEN
                  RAISE EXCEPTION 'found more than one table of name %', tname;
              ELSEIF tcount = 0 THEN
                  RAISE EXCEPTION 'not found target table in pg_aocsmeta, table name:%', tname;
              END IF;
          END IF;
      
          EXECUTE 'ALTER TABLE ' || tname || ' SET WITH(REORGANIZE=TRUE)';
          RETURN TRUE;
      END;
      $$  LANGUAGE PLPGSQL;
    2. 使用管理員賬號或者表的owner升級需要的表,執行如下SQL:
      SELECT UPGRADE_AOCS_TABLE_META(table_name);
    3. 檢查表的meta version, SQL如下:
      SELECT version = 4 AS is_latest_version  FROM pg_appendonly WHERE relid = 'test'::REGCLASS

使用SortKey提升MetaScan性能

SortKey是AnalyticDB PostgreSQL版的另一個特性,可以讓表按指定的列排序。把MetaScan與SortKey結合使用,可以有效的提高MetaScan執行的性能。 列存表是通過block為單位來存儲數據的,MetaScan是通過meta信息判斷block是否滿足條件,跳過不滿足條件的block,從而減少I/O,提升掃描性能的。如果過濾列的數值分布的非常散,例如每個block都有,這樣的話,即使過濾率很好也需要掃描所有的block,掃描性能低下。如果在表上以過濾列創建SortKey,則可以把列上相同的值集中到連續的block內,這樣MetaScan就可以快速過濾掉不需要的block,從而提升掃描性能。

創建SortKey,請參見 列存表使用排序鍵和粗糙集索引加速查詢

MetaScan的限制

目前版本MetaScan與ORCA優化器不兼容,在開啟ORCA優化器時,無法使用MetaScan。查看當前優化器的方式是:
SHOW OPTIMIZER;
on表示是ORCA優化器。優化器相關信息,請參見兩種優化器的選擇