雲原生資料倉儲AnalyticDB PostgreSQL版支援通過Hint幹預執行計畫,如指定SQL語句使用或不使用ORCA最佳化器,幹預JOIN順序和JOIN類型。
指定SQL語句使用或不使用ORCA最佳化器
開啟Hint幹預計劃並啟用Hint註冊規則,語句如下:
SET pg_hint_plan.enable_hint to on;
SET pg_hint_plan.enable_hint_table to on;
建立用於測試的表t1和表t2,建表語句如下:
CREATE TABLE t1 (id int PRIMARY KEY, val int);
CREATE TABLE t2 (id int PRIMARY KEY, val int);
分別往兩張表中插入測試資料,語句如下:
INSERT INTO t1 SELECT i, i % 100 FROM (SELECT generate_series(1, 10000) i) t;
INSERT INTO t2 SELECT i, i % 10 FROM (SELECT generate_series(1, 1000) i) t;
建立索引,語句如下:
CREATE INDEX t1_val ON t1 (val);
CREATE INDEX t2_val ON t2 (val);
強制關閉ORCA最佳化器,語句如下:
SELECT * FROM hint_plan.insert_hint_table($$EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.val = t2.val WHERE t1.id = 1;$$);
返回資訊如下:
-[ RECORD 1 ]
id | 1
norm_query_string | explain select * from t1 join t2 on t1.val = t2.val;
application_name |
hints | set(optimizer off)
query_hash | -2169095602568752481
enable | t
prepare_param_strings | {}
輸出執行計畫,語句如下:
EXPLAIN SELECT * FROM t1 JOIN t2 ON t1.val = t2.val WHERE t1.id = 3;
強制關閉後,執行計畫使用了Postgres query optimizer最佳化器,返回資訊如下:
QUERY PLAN
Gather Motion 3:1 (slice2; segments: 3) (cost=8.25..27.61 rows=11 width=16)
-> Hash Join (cost=8.25..27.61 rows=4 width=16)
Hash Cond: (t2.val = t1.val)
-> Seq Scan on t2 (cost=0.00..13.00 rows=334 width=8)
-> Hash (cost=8.22..8.22 rows=1 width=8)
-> Broadcast Motion 1:3 (slice1; segments: 1) (cost=0.16..8.22 rows=3 width=8)
-> Index Scan using t1_pkey on t1 (cost=0.16..8.18 rows=1 width=8)
Index Cond: (id = 3)
Optimizer: Postgres query optimizer
(9 rows)
強制啟用ORCA最佳化器,語句如下:
SELECT * FROM hint_plan.insert_hint_table($$SELECT * FROM t1 WHERE t1.id = 1;$$);
返回資訊如下:
-[ RECORD 1 ]
id | 2
norm_query_string | select * from t1 where t1.id = $1;
application_name |
hints | set(optimizer on) set(rds_optimizer_options 0)
query_hash | -8281826471521807124
enable | t
prepare_param_strings | {}
輸出執行計畫,語句如下:
EXPLAIN SELECT * FROM t1 WHERE t1.id = 2;
強制啟用後,執行計畫使用了ORCA最佳化器,返回資訊如下:
QUERY PLAN
Gather Motion 1:1 (slice1; segments: 1) (cost=0.00..6.00 rows=1 width=8)
-> Index Scan using t1_pkey on t1 (cost=0.00..6.00 rows=1 width=8)
Index Cond: (id = 1)
Optimizer: Pivotal Optimizer (GPORCA) version 3.86.0
(4 rows)
幹預JOIN順序和JOIN類型
開啟Hint幹預計劃並啟用Hint註冊功能,語句如下:
SET optimizer to off;
SET pg_hint_plan.enable_hint to on;
SET pg_hint_plan.enable_hint_table to on;
建立用於測試的表t1和表t2,建表語句如下:
CREATE TABLE t1 (id int PRIMARY KEY, val int);
CREATE TABLE t2 (id int PRIMARY KEY, val int);
分別往兩張表中插入測試資料,語句如下:
INSERT INTO t1 SELECT i, i % 100 FROM (SELECT generate_series(1, 10000) i) t;
INSERT INTO t2 SELECT i, i % 10 FROM (SELECT generate_series(1, 1000) i) t;
建立索引,語句如下:
CREATE INDEX t1_val ON t1 (val);
CREATE INDEX t2_val ON t2 (val);
輸出執行計畫,語句如下:
EXPLAIN SELECT * FROM t1, t2 WHERE t1.id = t2.id and t1.val < 100 and t2.val > 1;
此處為預設執行計畫,JOIN類型和JOIN順序為HashJoin(t1 t2) Leading((t1 t2))
,返回資訊如下:
QUERY PLAN
Gather Motion 3:1 (slice1; segments: 3) (cost=25.50..208.00 rows=800 width=16)
-> Hash Join (cost=25.50..208.00 rows=267 width=16)
Hash Cond: (t1.id = t2.id)
-> Seq Scan on t1 (cost=0.00..137.00 rows=3334 width=8)
Filter: (val < 100)
-> Hash (cost=15.50..15.50 rows=267 width=8)
-> Seq Scan on t2 (cost=0.00..15.50 rows=267 width=8)
Filter: (val > 1)
Optimizer: Postgres query optimizer
以下幾種方法可以幹預JOIN順序和JOIN類型: