PolarDB PostgreSQL版支援通過控制台添加列存索引唯讀節點和直接使用列存索引外掛程式這兩種方式來開啟和使用列存索引。您可以根據實際業務情境選擇最適合您的使用方式。
適用範圍
叢集版本:
PostgreSQL 14(核心小版本為2.0.14.10.20.0及以上)
PostgreSQL 15(核心小版本為2.0.15.15.7.0及以上)
PostgreSQL 16(核心小版本為2.0.16.8.3.0及以上)
PostgreSQL 17(核心小版本為2.0.17.7.5.0及以上)
wal_level參數的值需設定為logical,即在預寫式日誌WAL(Write-Ahead Logging)中增加支援邏輯編碼所需的資訊。說明您可以通過控制台設定wal_level參數。修改該參數後叢集將會重啟,請在修改參數前做好業務安排,謹慎操作。
原表必須包含主鍵,並且在建立列存索引時,需要將主鍵列加入列存索引中。建議使用
SERIAL或BIGSERIAL類型的主鍵,這將顯著提高資料同步的效率。一張表只能建立一個列存索引。
開啟列存索引功能
對於不同的PolarDB PostgreSQL版核心版本,開啟列存索引的方式不同:
建立列存索引
1. 為指定列或所有列建立列存索引
文法說明
-- 為部分列建立索引
CREATE INDEX [ CONCURRENTLY ] csi_index_name ON table_name USING CSI(column1,column2,...);
-- 為所有列建立索引
CREATE INDEX [ CONCURRENTLY ] csi_index_name ON table_name USING CSI;參數說明
參數 | 描述 |
CONCURRENTLY | 可選,使用併發模式建立索引。不會阻塞原表的寫入操作,適用於對線上已有表的索引建立。 |
csi_index_name | 自訂的列存索引名稱。 |
table_name | 需要建立列存索引的表名稱。 |
column1,column2,... | 指定建立列存索引的表的具體列,如不指定則為所有列建立索引。 |
樣本
準備基礎測試表
sales。CREATE TABLE sales (sale_id int primary key, name CHAR(10), amount int);建立列存索引。由於一張表只能建立一個列存索引,請選擇執行以下任一語句以為指定表建立列存索引。
指定列建立列存索引
CREATE INDEX idx_csi_sales ON sales USING CSI(sale_id, amount);所有列建立列存索引
CREATE INDEX idx_csi_sales ON sales USING CSI;使用併發模式為指定列建立列存索引
併發模式下建立列存索引不會阻塞原表的寫入操作,適用於對線上已有表進行索引建立。
CREATE INDEX CONCURRENTLY idx_csi_sales ON sales USING CSI(sale_id, amount);建立索引成功後可使用以下語句查看索引情況:
SELECT * FROM pg_indexes WHERE tablename = 'sales';
2. 查看索引建立進度
為資料量較大的表建立列存索引可能耗時較長,可通過以下方式查看索引建立的進度。同時,您可以調整相關參數以提升索引建立的速度。
SELECT * FROM pg_stat_progress_create_index;3. (可選)取消索引建立
當建立索引耗時較長,且建立索引的進程對現有業務產生了影響,您可通過pg_cancel_backend或pg_terminate_backend取消索引的建立,函數中需要的pid可通過2. 查看索引建立進度擷取。
SELECT pg_cancel_backend(pid);
SELECT pg_terminate_backend(pid);4. 查看索引大小
可以使用pg_relation_size函數查看索引大小,並結合pg_size_pretty函數以更友好的方式進行顯示。
SELECT * FROM pg_size_pretty(pg_relation_size('csi_index_name'));例如,查看之前建立的列存索引佔用的儲存空間大小。
SELECT * FROM pg_size_pretty(pg_relation_size('idx_csi_sales'));5. (可選)列存索引資料即時性
PolarDB PostgreSQL版叢集不僅支援對歷史資料建立列存索引,還能夠自動將行存表中的新資料同步至列存索引。當使用CREATE INDEX語句為表建立列存索引後,之後新增的資料將即時寫入列存索引,且無需對該過程進行額外操作。
列存索引通過PolarDB PostgreSQL版的邏輯複製機制實現資料同步,需對WAL日誌進行解碼並將其同步至列存引擎,在預設配置下,該機制能夠承載約20萬QPS的寫入壓力(基於Sysbench oltp_insert標準測試)。
查詢當前資料同步延遲
SELECT active_pid, database, slot_name, pg_size_pretty(pg_current_wal_lsn() - confirmed_flush_lsn) AS size FROM pg_replication_slots WHERE slot_name LIKE 'csi_sync_%';當size維持在50 MB以內時,列存資料可在秒級實現同步重新整理。
提高資料同步效率
為滿足某些業務情境下的行列資料即時性的要求,您可以通過調整參數
polar_csi.update_interval和polar_csi.update_batch_count來提升列存索引的即時性。
使用列存索引
1. 配置參數
在建立完列存索引後,可以通過如下參數來控制SQL查詢語句是否使用列存索引。
參數 | 說明 |
polar_csi.enable_query | 是否允許查詢語句使用列存索引,取值如下:
|
polar_csi.cost_threshold | 查詢代價閾值,是否使用列存索引。如果查詢代價小於當前設定閾值,使用行存引擎,反之使用列存引擎。 說明 將值設定為0時,所有查詢語句都將優先採用列存索引。不建議在實際業務中將值設定為0,請根據行存引擎與列存引擎的負載情況動態調整該值。 |
2. 配置參數生效範圍
全域範圍
您可以通過控制台設定polar_csi.enable_query參數為on,讓所有資料庫中的查詢語句都會嘗試使用列存索引。
會話級
會話內的所有查詢都會嘗試使用列存索引。
SET polar_csi.enable_query = ON;SQL語句級
會話內的單個SQL查詢語句使用列存索引,可通過Hint方式實現。
依賴pg_hint_plan外掛程式的能力,需要在目標資料庫執行CREATE EXTENSION pg_hint_plan;以安裝該外掛程式。
僅設定
polar_csi.enable_query。-- 允許查詢語句使用列存索引 /*+ SET (polar_csi.enable_query on) */ SELECT COUNT(*) FROM sales;設定
polar_csi.enable_query與polar_csi.cost_threshold。-- 允許查詢語句使用列存索引並且設定查詢代價閾值為0 /*+SET (polar_csi.enable_query on) SET(polar_csi.cost_threshold 0)*/ SELECT COUNT(*) FROM sales;
3. 查看SQL是否使用列存索引
通過Explain或Explain Analyze等工具列印查詢計劃,出現CSI Executor關鍵詞時即表示該查詢已經使用列存索引。
EXPLAIN SELECT COUNT(*) FROM sales;返回結果如下:
QUERY PLAN
--------------
CSI Executor
(1 row)4. (可選)配置列存索引資料查詢一致性
PolarDB PostgreSQL版列存索引支援兩種查詢一致性層級,以滿足不同業務需求。
最終一致性(預設):適用於寫入負載高,但對資料即時性要求低的查詢。
強一致性:在列存資料與行存資料完全一致後再返回查詢結果。
PolarDB PostgreSQL版的列存索引即時性可以達到秒級,但當寫入負載過大時,列存索引的資料延遲會升高。預設的一致性層級為最終一致性,所以當寫入負載過大,且SQL查詢使用列存索引時,可能無法查出最新的資料。
為滿足某些業務情境下的行列強一致性要求,您可以通過將參數polar_csi.forward_replay_wait調整為強一致性讀(on)來實現。當查詢時,系統會等待列存索引的資料與行存資料一致時才會執行。
刪除與重建列存索引
由於當前PolarDB PostgreSQL版叢集不支援修改列存索引,若您需要在已有的列存索引中添加其他指定列,您可以選擇刪除索引重新建立或重建列存索引。
刪除列存索引
文法說明
DROP INDEX csi_index_name;參數說明
參數 | 描述 |
csi_index_name | 需要刪除的列存索引名稱。 |
樣本
刪除之前建立的列存索引。
DROP INDEX idx_csi_sales; 重建列存索引
文法說明
REINDEX INDEX csi_index_name;參數說明
參數 | 描述 |
csi_index_name | 需要重建的列存索引名稱。 |
樣本
重建之前建立的列存索引。
REINDEX INDEX idx_csi_sales; 調整列存索引參數提升效能
提升索引建立速度
索引建立速度與多個參數有關,如下所示:
參數名 | 取值範圍 | 預設值 | 描述 |
polar_csi.memory_limit | 1~1048576 | 4096 | 列存索引可以使用的記憶體大小,單位:MB。 記憶體閾值越大,索引建立越快。請根據叢集規格來調整該參數的值,建議不超過叢集記憶體的25%,否則可能造成OOM的風險。 說明
|
polar_csi.flush_count | 2048~20480000 | 204800 | 建立索引時,批次提交的行數。 增加行數能夠提高建立效率,但同時也需要佔用更多記憶體。 |
提升列存索引的即時性
通過調整這些參數,您可以提高行列轉換的速度,從而提升列存索引資料的即時性。
參數名 | 取值範圍 | 預設值 | 作用 |
polar_csi.update_interval | 0~3600 | 1 | 定期更新行列資料即時性的時間間隔,單位:秒。 增大更新間隔可以合并同類型的小事務,從而在事務數量較多時提高資料更新效率。 說明
|
polar_csi.update_batch_count | 1024~4294967295 | 100000 | 批次更新行數的閾值。 一個更新事務的最大行數,增加該閾值可以提升資料更新的效率。 說明
|
提升查詢速度
查詢效能主要與以下參數有關,可通過調整參數值提升查詢效能:
參數名 | 取值範圍 | 預設值 | 作用 |
polar_csi.exec_parallel | 1~512 | 2 | 列存索引的並行度,即一條SQL語句可以使用的CPU資源,一般來說並行度越大效能越好。 實際取值與叢集資源規格相關,請根據叢集規格來調整該參數的值,建議不超過計算節點的CPU核心數。 |
polar_csi.memory_limit | 1~1048576 | 4096 | 列存索引可以使用的記憶體大小,單位:MB。 記憶體閾值越大,索引建立越快。請根據叢集規格來調整該參數的值,建議不超過叢集記憶體的25%,否則可能造成OOM的風險。 說明
|
polar_csi.cost_threshold | 1~1000000000 | 50000 | 當查詢代價小於該閾值時,查詢語句不會使用列存索引來加速。實際取值請根據實際業務負載進行調整。
說明
|
polar_csi.forward_replay_wait | on|off | off | 列存索引資料查詢一致性層級,取值如下:
|





