當您進行複雜查詢並期望快速獲得查詢結果時,可以利用雲資料庫RDS PostgreSQL的AP加速引擎(rds_duckdb)。該引擎提供了列存表和向量化執行能力,顯著提升複雜查詢的執行速度,且無需修改原始查詢語句,從而確保您能夠方便且高效地擷取結果。
您可以加入RDS PostgreSQL外掛程式交流DingTalk群(103525002795),進行諮詢、交流和反饋,擷取更多關於外掛程式的資訊。
功能簡介
rds_duckdb在RDS PostgreSQL中引入了高效、資源友好的DuckDB,以增強分析型查詢能力。該外掛程式可以將RDS PostgreSQL中的本地表匯出為列存表,並啟用分析型查詢加速(Analytical Processing Query Acceleration,簡稱AP)功能,顯著提升了複雜查詢的執行速度,從而更好地滿足分析型業務的需求。
前提條件
執行個體大版本為RDS PostgreSQL 12及以上。
執行個體核心小版本為20241030及以上。
已將rds_duckdb添加到shared_preload_libraries的運行參數值中。
配置參數的詳情操作請參見設定執行個體參數。例如,將運行參數值改為'pg_stat_statements,auto_explain,rds_duckdb'。
說明 當執行個體大版本為RDS PostgreSQL 15,小版本為20250228,預設開啟列存表資料的自動增量同步處理。
建立和刪除外掛程式
使用高許可權賬戶進行外掛程式的建立與刪除操作。
建立外掛程式
CREATE EXTENSION rds_duckdb;
查看外掛程式使用的DuckDB核心版本
SELECT rds_duckdb.duckdb_version();
刪除外掛程式
DROP EXTENSION rds_duckdb;
管理列存表
建立列存表
使用以下命令,將RDS PostgreSQL本地表(使用者表、物化視圖、外表等)匯出為一份列存表,該列存表將用於加速分析型查詢。
說明 當執行個體的大版本為RDS PostgreSQL 15,小版本為20250228時,預設啟用列存表資料的自動增量同步處理功能。在建立列存表之前,您可以配置目標RDS PostgreSQL執行個體及本地表,以實現列存表資料的自動增量同步處理。詳情請參見設定列存表自動增量同步處理。
SELECT rds_duckdb.create_duckdb_table('本地表名稱');
重新整理列存表
使用以下命令,依據RDS PostgreSQL本地表的最新資料重新整理匯出的列存表,同時更新表結構資訊和資料內容。
SELECT rds_duckdb.refresh_duckdb_table('本地表名稱');
查看列存表大小
SELECT rds_duckdb.duckdb_table_size('本地表名稱');
查看當前資料庫中所有匯出表大小
SELECT rds_duckdb.duckdb_database_size();
刪除列存表
SELECT rds_duckdb.drop_duckdb_table('本地表名稱');
管理AP加速
rds_duckdb目前支援加速唯讀查詢。開啟AP加速後,當SQL類型為查詢且涉及的表均有對應的DuckDB列存表時,SQL將由DuckDB執行以實現加速。如果SQL屬於暫不支援的DML、DDL操作或包含不存在的列存表,則將回退到RDS PostgreSQL中執行。
對於回退到RDS PostgreSQL執行的SQL,系統會給出警告提示,格式為:WARNING: Trying to execute an operation with non-duckdb tables(test), fallback to PG。其中,括弧內顯示的是不包含對應DuckDB列存表的RDS PostgreSQL表。
非唯讀SQL查詢也會收到提示,顯示為:WARNING: Modification operations on DuckDB tables are currently not supported, fallback to PG。
開啟AP加速
SET rds_duckdb.execution = on;
設定AP加速參數
您可以在會話中通過調整參數配置來實現對AP加速效能的控制。例如:
SET rds_duckdb.worker_threads = 32;
SET rds_duckdb.memory_limit = 16384;
參數名稱 | 參數說明 | 取值建議 |
rds_duckdb.worker_threads | AP加速時使用的背景工作執行緒數量。 取值範圍:1~255。 預設值:1,表示只有一個背景工作執行緒。 | 建議希望實現顯著性能提升的使用者,將該值設定為CPU核心數。 該參數與執行機器的硬體密切相關,值越大,執行AP加速時CPU的負載越高。因此,需要根據實際情況合理設定該參數。 該參數設定較高時,可以獲得更優異的效能,然而CPU負載也會相應增加;反之,若該參數設定較低,則加速效果將會有所降低,但系統CPU負載也會隨之減少。
|
rds_duckdb.memory_limit | AP加速時使用的記憶體限制。 單位:MB(配置參數時無需添加單位)。 取值範圍:1~INT32_MAX。 預設值:100,表示上限為100 MB。 | 建議希望實現顯著性能提升的使用者,將該值設定為儘可能大的數值。 該參數與執行機器的硬體密切相關,值越大,執行AP加速時記憶體的使用量越高。因此,需要根據實際情況合理設定該參數。 預設參數值設定較為保守,建議使用者根據裝置的實際情況進行相應調整。 該值過小時可能會影響大表匯出列存表的過程,並影響AP加速的效能。
|
關閉AP加速
SET rds_duckdb.execution = off;
設定列存表自動增量同步處理
當執行個體的大版本為RDS PostgreSQL 15,小版本為20250228時,預設啟用列存表資料的自動增量同步處理功能。建立列存表之前,您需要執行以下操作,配置目標RDS PostgreSQL執行個體和本地表。
在外掛程式管理中檢查看rds_duckdb的版本,並將其升級到1.3。
設定執行個體參數,將wal_level參數的運行值改為logical。
(可選)當目標本地表未定義主鍵時,請執行以下命令,為該表設定REPLICA IDENTITY索引作為複製鍵。
ALTER TABLE <本地表名稱> REPLICA IDENTITY USING INDEX <index_name>;
使用具備replication許可權的帳號或高許可權帳號建立列存表。
查看列存表的同步狀態及同步位點進度
SELECT * FROM rds_duckdb.duckdb_sync_stat;
返回樣本及參數說明
返回樣本:
sync_table | sync_status_description | sync_error_description | confirmed_lsn
------------+-------------------------+------------------------------------------+---------------
test | not syncing | no primary key or replica identity index |
test2 | not syncing | no primary key or replica identity index |
test3 | data syncing | no errors | 0/250D1E8
test4 | not syncing | no primary key or replica identity index |
test5 | data syncing | no errors | 0/250D1E8
test6 | data syncing | no errors | 0/250D1E8
test7 | data syncing | no errors | 0/250D1E8
test8 | data syncing | no errors | 0/250D1E8
參數說明:
參數 | 說明 |
sync_status_description | 列存表的同步狀態。 |
sync_error_description | 未進行增量同步處理的列存表的原因。 no errors:沒有問題。 dml replay conflict:DML操作導致增量回放衝突。 ddl replay conflict:DDL操作導致增量回放衝突。 no primary key or replica identity index:列存表所對應的RDS PostgreSQL表缺乏主鍵或REPLICA IDENTITY索引。 unsupported relation type:暫不支援的同步表類型,例如分區表、視圖、物化視圖。 rds_duckdb.enable_sync not set:全域同步GUC尚未開啟。
說明 執行個體的大版本為RDS PostgreSQL 15,小版本為20250228時,預設開啟。 removing duckdb table:進行中列存表的刪除操作。
|
查看SQL執行計畫
使用EXPLAIN語句查看開啟和關閉AP加速後,SQL語句的執行計畫。例如:
開啟AP加速後,SQL語句的執行計畫如下。
開啟AP加速
tpch_10x=# SET rds_duckdb.execution = on;
SET
tpch_10x=# EXPLAIN SELECT
tpch_10x-# 100.00 * sum(
tpch_10x(# CASE WHEN p_type LIKE 'PROMO%' THEN
tpch_10x(# l_extendedprice * (1 - l_discount)
tpch_10x(# ELSE
tpch_10x(# 0
tpch_10x(# END) / sum(l_extendedprice * (1 - l_discount)) AS promo_revenue
tpch_10x-# FROM
tpch_10x-# lineitem,
tpch_10x-# part
tpch_10x-# WHERE
tpch_10x-# l_partkey = p_partkey
tpch_10x-# AND l_shipdate >= date '1995-09-01'
tpch_10x-# AND l_shipdate < CAST('1995-10-01' AS date);
QUERY PLAN
------------------------------------------------------------
Custom Scan (DuckDBNode) (cost=0.00..0.00 rows=0 width=0)
DuckDB Plan:
┌───────────────────────────┐
│ PROJECTION │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Projections: │
│ promo_revenue │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Estimated Cardinality: │
│ 1 │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│ UNGROUPED_AGGREGATE │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Aggregates: │
│ sum(#0) │
│ sum(#1) │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│ PROJECTION │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Projections: │
│ CASE WHEN (prefix(p_type,│
│ 'PROMO')) THEN (CAST( │
│ (l_extendedprice * (1.000 │
│ - CAST(l_discount AS │
│ DECIMAL(18,3)))) AS │
│ DECIMAL(20,5))) ELSE 0 │
│ .00000 END │
│ (l_extendedprice * (1.000 │
│ - CAST(l_discount AS │
│ DECIMAL(18,3)))) │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Estimated Cardinality: │
│ 6600339 │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│ HASH_JOIN │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Join Type: │
│ INNER │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Conditions: ├──────────────┐
│ l_partkey = p_partkey │ │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │
│ Estimated Cardinality: │ │
│ 6600339 │ │
└─────────────┬─────────────┘ │
┌─────────────┴─────────────┐┌─────────────┴─────────────┐
│ SEQ_SCAN ││ SEQ_SCAN │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ││ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Stringified: ││ Stringified: │
│ lineitem ││ part │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ││ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ Projections: ││ Projections: │
│ l_partkey ││ p_partkey │
│ l_extendedprice ││ p_type │
│ l_discount ││ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ││ Estimated Cardinality: │
│ Filters: ││ 2000000 │
│ l_shipdate>='1995-09-01': ││ │
│ :DATE AND l_shipdate<'1995││ │
│ -10-01'::DATE AND ││ │
│ l_shipdate IS NOT NULL ││ │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ││ │
│ Estimated Cardinality: ││ │
│ 11997210 ││ │
└───────────────────────────┘└───────────────────────────┘
(71 rows)
關閉AP加速後,SQL語句的執行計畫如下。
關閉AP加速
tpch_10x=# SET rds_duckdb.execution = off;
SET
tpch_10x=# EXPLAIN SELECT
100.00 * sum(
CASE WHEN p_type LIKE 'PROMO%' THEN
l_extendedprice * (1 - l_discount)
ELSE
0
END) / sum(l_extendedprice * (1 - l_discount)) AS promo_revenue
FROM
lineitem,
part
WHERE
l_partkey = p_partkey
AND l_shipdate >= date '1995-09-01'
AND l_shipdate < CAST('1995-10-01' AS date);
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
Finalize Aggregate (cost=1286740.42..1286740.43 rows=1 width=32)
-> Gather (cost=1286739.96..1286740.37 rows=4 width=64)
Workers Planned: 4
-> Partial Aggregate (cost=1285739.96..1285739.97 rows=1 width=64)
-> Parallel Hash Join (cost=1235166.04..1282419.39 rows=189747 width=33)
Hash Cond: (part.p_partkey = lineitem.l_partkey)
-> Parallel Seq Scan on part (cost=0.00..43232.15 rows=500016 width=29)
-> Parallel Hash (cost=1233776.40..1233776.40 rows=111171 width=20)
-> Parallel Seq Scan on lineitem (cost=0.00..1233776.40 rows=111171 width=20)
Filter: ((l_shipdate >= '1995-09-01'::date) AND (l_shipdate < '1995-10-01'::date))
JIT:
Functions: 17
Options: Inlining true, Optimization true, Expressions true, Deforming true
(13 rows)