HINT
Hint作為一種SQL補充語法,允許用戶通過相應(yīng)的語法改變SQL的執(zhí)行方式,實現(xiàn)SQL的特殊優(yōu)化。Hologres從V2.2版本開始,提供Hint語法,以便您使用Hint改變SQL的執(zhí)行方式,輔助業(yè)務(wù)進行SQL調(diào)優(yōu),實現(xiàn)更好的性能。本文為您介紹Hint的用法以及使用場景。
使用限制
Hint功能要求Hologres實例版本必須為V2.2及以上版本,若您的實例為V2.1或以下版本,請升級實例。
使用說明
目前支持對常規(guī)表(包括外部表)、子查詢、CTE(Common Table Expression)或視圖指定Hint。
Hint的所有內(nèi)容均包含在
/*+HINT
和*/
之間,Hint中不允許再出現(xiàn)注釋。Hint關(guān)鍵詞不區(qū)分大小寫。
一段Hint內(nèi)容中可以同時包含多個Hint關(guān)鍵詞。
Hint有對應(yīng)的層級,指定的參數(shù)為當前作用域內(nèi)的可見參數(shù),不可使用子查詢或父查詢中的參數(shù),如下述SQL中的Hint
/*+HINT Leading(tt t2) */
只能指定tt
和t2
為參數(shù),無法使用t1、t3、t
。同理,/*+HINT Leading(t t1) */
的位置只能使用t
和t1
,無法使用t2、t3、tt
。SELECT /*+HINT Leading(t t1) */ * FROM t1 join ( SELECT /*+HINT Leading(tt t2) */ * FROM t2 join ( SELECT * FROM t3 ) tt ) t;
對于
INSERT INTO ... SELECT
語句,INSERT的作用域包含目標表和后面SELECT最外層的源表,SELECT的作用域不包含目標表。且為了避免沖突情況,當在INSERT后指定了對應(yīng)的Hint時,SELECT中不能再次指定Hint。示例如下:正確示例
--示例1:INSERT后的Hint支持指定target、t1、t2為參數(shù)。 INSERT /*+HINT Leading(target (t1 t2)) */ INTO target SELECT t1.a,t2.b FROM t1 JOIN t2 ON t1.a=t2.a --示例2:SELECT后的Hint只支持指定t1、t2為參數(shù)。 INSERT INTO target SELECT /*+HINT Leading(t2 t1) */ t1.a,t2.b FROM t1 JOIN t2 ON t1.a=t2.a;
錯誤示例
--不能在INSERT和SELECT后同時使用Hint,否則執(zhí)行會報錯。 INSERT /*+HINT Leading(target (t1 t2)) */ INTO target SELECT /*+HINT Leading(t2 t1) */ t1.a,t2.b FROM t1 JOIN t2 ON t1.a=t2.a; --報錯信息 ERROR: insert statement with hint should not have sub select with hint at the same time
GUC Hint僅對當前Query級別生效,且在任意層級下設(shè)置都會影響整個Query。當前Query執(zhí)行完成后,后續(xù)Query將不會受GUC Hint的影響。
示例:在子查詢中設(shè)置GUC關(guān)閉
count distinct reuse
會對整個Query都生效。SELECT count(DISTINCT a), count(DISTINCT b) FROM ( SELECT /*+HINT set(hg_experimental_enable_reuse_cte_of_count_distinct off) */ t1.a t2.b FROM t1 JOIN t2 ON t1.a = t2.a)
Hint允許在參數(shù)中使用括號以提高優(yōu)先級,允許任意的括號嵌套。例如
Leading(t1 t2 t3)
表示t1和t2先進行Join,再Join t3,而Leading(t1 (t2 t3))
表示先執(zhí)行t2 Join t3
,再和t1進行Join。Join Method Hint和Join Order Hint均要求至少兩個以上的有效參數(shù),參數(shù)不足時,Hint不會生效。
說明有效參數(shù):指當前層級作用域中包含的表、子查詢、CTE或視圖,如
Leading(t1 t1)
和Leading(t1)
中都只有t1一個有效參數(shù)。Runtime Filter Hint只能對HashJoin生效。
當生成的候選計劃不包含Join Method指定的表連接方式時,對應(yīng)的Hint不會生效。例如指定HashJoin(t1 t2),但生成的計劃為
t1 Join t3
后再Join t2,此時Hint不會生效,可以通過添加Leading(t1 t2)
指定Join Order來強制執(zhí)行連接順序。SELECT后連續(xù)多段由
/*HINT+
和*/
括起的內(nèi)容,只有第一段會被作為Hint處理。例如SELECT /*+HINT HashJoin(t1 t2) */ /*+HINT Leading(t1 t2) */ ...
語句中,只有HashJoin會被處理,而Leading的內(nèi)容會被忽略。同一類Hint中定義的表存在沖突時,以先定義的Hint為準。
說明沖突包含如下幾種場景:
兩個Hint中包含相同的表。
表集合相同。
Join Order時,Hint參數(shù)互為子集。
Join Method、Runtime Filter或skew Join時,Hint參數(shù)不互為子集。
示例1:
HashJoin(t1 t2)
和NestLoop(t2 t1)
中包含相同的表,產(chǎn)生沖突,只解析HashJoin(t1 t2)
。SELECT /*+HINT HashJoin(t1 t2) NestLoop(t2 t1) */ ...
示例2:
Leading(t1 t2)
和Leading(t1 t2 t3)
互為子集,產(chǎn)生沖突,因此只解析Leading(t1 t2)
。SELECT /*+HINT Leading(t1 t2) Leading(t1 t2 t3) */ ...
當指定的Hint計劃不滿足生成條件時,會導(dǎo)致無法生成執(zhí)行計劃。例如指定兩表進行NestLoop和Right Join時,由于不支持這樣的計劃,會報錯
ERROR: ORCA failed to produce a plan : No plan has been computed for required properties
,即屬性不滿足無法生成計劃。
Hint關(guān)鍵詞
目前各類型支持的Hint關(guān)鍵詞及對應(yīng)的參數(shù)格式如下。
類型 | 參數(shù)格式 | 描述 | 示例 | 注意事項 |
Join Method |
| 強制使用嵌套循環(huán)連接。 |
| 至少包含兩個有效參數(shù)才能觸發(fā)Hint。 說明 有效參數(shù)指當前層級作用域中包含的表、子查詢、CTE(Common Table Expression)或視圖。 |
| 強制使用HashJoin連接。 |
| ||
Join Order |
| 強制Join連接按指定順序進行。 |
| |
| 強制定義Join連接的順序和方向。 說明 Join pair是一對用括號括起來的表或其他連接對,可以形成嵌套結(jié)構(gòu)。 |
| ||
Runtime Filter |
| 強制對指定表上的HashJoin使用Runtime Filter。 |
| 只能對HashJoin生效。 |
GUC |
| 在構(gòu)造計劃時,指定GUC參數(shù)值。 說明
|
| 僅對當前Query級別生效,當前Query執(zhí)行完成后,后續(xù)Query將不會受GUC Hint的影響。 |
使用步驟
通過GUC參數(shù)開啟Hint功能。
根據(jù)需要選擇在Session級別或DB級別開啟,方式如下。
Session級別開啟。
SET pg_hint_plan_enable_hint=on;
DB級別開啟,新建連接后生效。
ALTER database <dbname> SET pg_hint_plan_enable_hint=on;
書寫Hint。
使用如下格式書寫Hint:
SELECT|UPDATE|INSERT|DELETE /*+HINT <HintName(params)> */ ...
HintName(params)
表示Hint關(guān)鍵詞及對應(yīng)參數(shù),詳情請參見Hint關(guān)鍵詞。說明Hint關(guān)鍵詞不區(qū)分大小寫。
僅允許直接在INSERT、UPDATE、DELETE和SELECT關(guān)鍵字后指定Hint。
Hint內(nèi)容應(yīng)位于
/*+HINT
和*/
之間。
執(zhí)行對應(yīng)SQL。
使用場景
下述以具體示例為您介紹Hint的使用場景。示例表的DDL語句如下:
CREATE TABLE target (a int primary key, b int);
CREATE TABLE t1 (a int, b int);
CREATE TABLE t2 (a int, b int);
CREATE TABLE t3 (a int);
CREATE TABLE t4 (a int);
使用Hint調(diào)整Join Order
Join Order主要用于調(diào)整表Join的順序,不合理的Join Order會對SQL查詢性能產(chǎn)生極大影響,而造成Join Order不合理的原因通常為統(tǒng)計信息缺失或統(tǒng)計信息不準確。
統(tǒng)計信息缺失:通常是因為未及時執(zhí)行Analyze操作導(dǎo)致,Analyze詳情請參見ANALYZE和AUTO ANALYZE。
統(tǒng)計信息不準確:通常發(fā)生在進行了過濾或Join操作之后,統(tǒng)計信息過時,導(dǎo)致實際結(jié)果集和預(yù)估行數(shù)發(fā)生較大的偏差。
當Join Order不合理時,您可以根據(jù)業(yè)務(wù)實際進行手動使用GUC或者Hint調(diào)整。相比GUC的方式,通過Hint調(diào)整Join Order會更加簡單方便。
如下SQL示例中,Join指的是t1 Join t2
,HashJoin需要使用小表構(gòu)建哈希表(即執(zhí)行計劃中Hash算子下方的部分),如果實際上t2表的行數(shù)遠大于t1,SQL查詢性能會降低。解決方法除更新統(tǒng)計信息(執(zhí)行Analyze操作)之外,您還可以使用Hint調(diào)整Join Order。例如:使用Leading(t2 t1)
將Join順序調(diào)整為t2 Join t1
后,執(zhí)行計劃更加合理,且執(zhí)行效率更高。
SQL示例
SELECT /*+HINT Leading(t2 t1) */ t1.a FROM t1 JOIN t2 ON t1.a = t2.a;
執(zhí)行計劃對比
未開啟Hint的執(zhí)行計劃
QUERY PLAN ----------------------------------------------------------------------------------- Gather (cost=0.00..10.07 rows=1000 width=4) -> Hash Join (cost=0.00..10.05 rows=1000 width=4) Hash Cond: (t1.a = t2.a) -> Redistribution (cost=0.00..5.01 rows=1000 width=4) Hash Key: t1.a -> Local Gather (cost=0.00..5.00 rows=1000 width=4) -> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=4) -> Hash (cost=5.01..5.01 rows=1000 width=4) -> Redistribution (cost=0.00..5.01 rows=1000 width=4) Hash Key: t2.a -> Local Gather (cost=0.00..5.00 rows=1000 width=4) -> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=4)
開啟Hint的執(zhí)行計劃
QUERY PLAN ----------------------------------------------------------------------------------- Gather (cost=0.00..10.07 rows=1000 width=4) -> Hash Join (cost=0.00..10.05 rows=1000 width=4) Hash Cond: (t2.a = t1.a) -> Redistribution (cost=0.00..5.01 rows=1000 width=4) Hash Key: t2.a -> Local Gather (cost=0.00..5.00 rows=1000 width=4) -> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=4) -> Hash (cost=5.01..5.01 rows=1000 width=4) -> Redistribution (cost=0.00..5.01 rows=1000 width=4) Hash Key: t1.a -> Local Gather (cost=0.00..5.00 rows=1000 width=4) -> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=4)
使用GUC Hint
在某些場景中,Query需要使用GUC參數(shù)才能達到更好的效果。GUC Hint主要用于設(shè)置Query級別的GUC參數(shù),類似于在Query執(zhí)行前設(shè)置GUC參數(shù)。通過GUC Hint可以高效的對某個Query設(shè)置GUC,Query執(zhí)行完成后,GUC參數(shù)即失效,以便降低對其他Query的影響。
SQL示例
SELECT /*+HINT set(hg_experimental_query_batch_size 512) */t1.a FROM t1 JOIN t2 ON t1.a = t2.a;
執(zhí)行計劃
QUERY PLAN Hash Join (cost=0.00..10.00 rows=1 width=4) Hash Cond: (t1.a = t2.a) -> Gather (cost=0.00..5.00 rows=1 width=4) -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t1 (cost=0.00..5.00 rows=1 width=4) -> Hash (cost=5.00..5.00 rows=1 width=4) -> Gather (cost=0.00..5.00 rows=1 width=4) -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t2 (cost=0.00..5.00 rows=1 width=4)
CTE和子查詢的Hint使用
在包含CTE和子查詢的場景下,使用Hint影響其執(zhí)行計劃。
SQL示例
WITH c1 AS ( SELECT /*+HINT Leading(t2 t1) */ t1.a FROM ( ( SELECT /*+HINT leading(t2 t1) */ t1.a FROM t1 JOIN t2 ON t1.a = t2.a ) AS t1 JOIN ( SELECT /*+HINT NestLoop(t4 t3) */ t4.a FROM t3 JOIN t4 ON t3.a = t4.a ) AS t2 ON t1.a = t2.a ) ), c2 AS ( SELECT /*+HINT leading(t1 t2) */ t2.a FROM ( ( SELECT /*+HINT Leading(t1 t2) */ t1.a FROM t1 JOIN t2 ON t1.a = t2.a ) AS t1 JOIN ( SELECT /*+HINT Leading(t4 t3) */ t4.a FROM t3 JOIN t4 ON t3.a = t4.a ) AS t2 ON t1.a = t2.a ) ) SELECT /*+HINT NestLoop(v2 v1) */ * FROM ( ( SELECT /*+HINT Leading (c1 t2) */ c1.a FROM c1 JOIN t2 ON c1.a = t2.a ) AS v1 JOIN ( SELECT /*+HINT Leading (t1 c2) */ c2.a FROM t1 JOIN c2 ON t1.a = c2.a ) AS v2 ON v1.a = v2.a ) ORDER BY v2.a;
執(zhí)行計劃
QUERY PLAN Sort (cost=0.00..10660048.36 rows=1 width=8) Sort Key: t4_1.a -> Gather (cost=0.00..10660048.36 rows=1 width=8) -> Nested Loop (cost=0.00..10660048.36 rows=1 width=8) Join Filter: ((t1.a = t4_1.a) AND (t1.a = t1_1.a) AND (t2_1.a = t1_1.a) AND (t2_1.a = t4_1.a)) -> Hash Join (cost=0.00..25.01 rows=1 width=8) Hash Cond: (t1_1.a = t4_1.a) -> Redistribution (cost=0.00..5.00 rows=1 width=4) Hash Key: t1_1.a -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t1 t1_1 (cost=0.00..5.00 rows=1 width=4) -> Hash (cost=20.00..20.00 rows=1 width=4) -> Hash Join (cost=0.00..20.00 rows=1 width=4) Hash Cond: ((t1_2.a = t4_1.a) AND (t1_2.a = t3_1.a) AND (t2_2.a = t3_1.a) AND (t2_2.a = t4_1.a)) -> Hash Join (cost=0.00..10.00 rows=1 width=8) Hash Cond: (t1_2.a = t2_2.a) -> Redistribution (cost=0.00..5.00 rows=1 width=4) Hash Key: t1_2.a -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t1 t1_2 (cost=0.00..5.00 rows=1 width=4) -> Hash (cost=5.00..5.00 rows=1 width=4) -> Redistribution (cost=0.00..5.00 rows=1 width=4) Hash Key: t2_2.a -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t2 t2_2 (cost=0.00..5.00 rows=1 width=4) -> Hash (cost=10.00..10.00 rows=1 width=8) -> Hash Join (cost=0.00..10.00 rows=1 width=8) Hash Cond: (t4_1.a = t3_1.a) -> Redistribution (cost=0.00..5.00 rows=1 width=4) Hash Key: t4_1.a -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t4 t4_1 (cost=0.00..5.00 rows=1 width=4) -> Hash (cost=5.00..5.00 rows=1 width=4) -> Redistribution (cost=0.00..5.00 rows=1 width=4) Hash Key: t3_1.a -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t3 t3_1 (cost=0.00..5.00 rows=1 width=4) -> Materialize (cost=0.00..10385.07 rows=40 width=8) -> Broadcast (cost=0.00..10385.07 rows=40 width=8) -> Hash Join (cost=0.00..10385.07 rows=1 width=8) Hash Cond: (t1.a = t2_1.a) -> Hash Join (cost=0.00..10380.07 rows=1 width=4) Hash Cond: ((t4.a = t1.a) AND (t3.a = t1.a) AND (t3.a = t2.a) AND (t4.a = t2.a)) -> Redistribution (cost=0.00..10370.07 rows=1 width=8) Hash Key: t4.a -> Nested Loop (cost=0.00..10370.07 rows=1 width=8) Join Filter: (t3.a = t4.a) -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t3 (cost=0.00..5.00 rows=1 width=4) -> Materialize (cost=0.00..5.00 rows=40 width=4) -> Broadcast (cost=0.00..5.00 rows=40 width=4) -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t4 (cost=0.00..5.00 rows=1 width=4) -> Hash (cost=10.00..10.00 rows=1 width=8) -> Hash Join (cost=0.00..10.00 rows=1 width=8) Hash Cond: (t2.a = t1.a) -> Redistribution (cost=0.00..5.00 rows=1 width=4) Hash Key: t2.a -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t2 (cost=0.00..5.00 rows=1 width=4) -> Hash (cost=5.00..5.00 rows=1 width=4) -> Redistribution (cost=0.00..5.00 rows=1 width=4) Hash Key: t1.a -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t1 (cost=0.00..5.00 rows=1 width=4) -> Hash (cost=5.00..5.00 rows=1 width=4) -> Redistribution (cost=0.00..5.00 rows=1 width=4) Hash Key: t2_1.a -> Local Gather (cost=0.00..5.00 rows=1 width=4) -> Seq Scan on t2 t2_1 (cost=0.00..5.00 rows=1 width=4)
INSERT Hint的使用
通常當目標表與源表有關(guān)聯(lián),需要進行Join Order或其他相關(guān)調(diào)整時,在INSERT INTO ... SELECT
的場景中使用Hint語法。INSERT INTO ... SELECT
的應(yīng)用場景中,SQL邏輯會比較復(fù)雜,需要業(yè)務(wù)根據(jù)計劃來添加Hint。
示例1:Hint作用于INSERT目標表和SELECT查詢最外層的源表。
執(zhí)行過程中,如果
t1 Join t2
產(chǎn)生的數(shù)據(jù)量較小,目標表target的數(shù)據(jù)量較大,當統(tǒng)計信息未更新時,可能無法生成最優(yōu)的執(zhí)行計劃,可以通過Hint來調(diào)整Join Order,實現(xiàn)更好的性能。SQL示例
--Hint作用在INSERT目標表和SELECT查詢最外層的源表 INSERT /*+HINT Leading(target (t1 t2)) */ INTO target SELECT t1.a,t2.b FROM t1 JOIN t2 ON t1.a=t2.a;
執(zhí)行計劃
QUERY PLAN ----------------------------------------------------------------------------------------------------------------- Gather (cost=0.00..26.57 rows=1000 width=8) -> Insert (cost=0.00..26.54 rows=1000 width=8) -> Project (cost=0.00..16.12 rows=1000 width=8) -> Hash Right Join (cost=0.00..15.12 rows=1000 width=12) Hash Cond: (target.a = t1.a) -> Local Gather (cost=0.00..5.00 rows=1000 width=4) -> Seq Scan on target (cost=0.00..5.00 rows=1000 width=4) -> Hash (cost=10.07..10.07 rows=1000 width=8) -> Redistribution (cost=0.00..10.07 rows=1000 width=8) Hash Key: t1.a -> Hash Join (cost=0.00..10.06 rows=1000 width=8) Hash Cond: (t1.a = t2.a) -> Redistribution (cost=0.00..5.01 rows=1000 width=4) Hash Key: t1.a -> Local Gather (cost=0.00..5.00 rows=1000 width=4) -> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=4) -> Hash (cost=5.01..5.01 rows=1000 width=8) -> Redistribution (cost=0.00..5.01 rows=1000 width=8) Hash Key: t2.a -> Local Gather (cost=0.00..5.00 rows=1000 width=8) -> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=8)
示例2:Hint作用于SELECT子查詢。
SQL示例
說明以下兩種INSERT語句使用Hint的場景是等效的。
INSERT INTO target SELECT /*+HINT Leading(t2 t1) */ t1.a,t2.b FROM t1 JOIN t2 ON t1.a=t2.a; INSERT /*+HINT Leading(t2 t1) */ INTO target SELECT t1.a,t2.b FROM t1 JOIN t2 ON t1.a=t2.a;
執(zhí)行計劃
QUERY PLAN ----------------------------------------------------------------------------------------------------------- Gather (cost=0.00..26.57 rows=1000 width=8) -> Insert (cost=0.00..26.54 rows=1000 width=8) -> Project (cost=0.00..16.12 rows=1000 width=8) -> Hash Left Join (cost=0.00..15.12 rows=1000 width=12) Hash Cond: (t1.a = target.a) -> Redistribution (cost=0.00..10.07 rows=1000 width=8) Hash Key: t1.a -> Hash Join (cost=0.00..10.06 rows=1000 width=8) Hash Cond: (t2.a = t1.a) -> Redistribution (cost=0.00..5.01 rows=1000 width=8) Hash Key: t2.a -> Local Gather (cost=0.00..5.00 rows=1000 width=8) -> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=8) -> Hash (cost=5.01..5.01 rows=1000 width=4) -> Redistribution (cost=0.00..5.01 rows=1000 width=4) Hash Key: t1.a -> Local Gather (cost=0.00..5.00 rows=1000 width=4) -> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=4) -> Hash (cost=5.00..5.00 rows=1000 width=4) -> Local Gather (cost=0.00..5.00 rows=1000 width=4) -> Seq Scan on target (cost=0.00..5.00 rows=1000 width=4)
UPDATE HINT的使用
UPDATE語句中HINT通常也用于目標表和源表有關(guān)聯(lián),需要進行手動調(diào)整的情況。
SQL示例
t1表數(shù)據(jù)量大于target,設(shè)置HINT使target表作為哈希表,達到調(diào)整Join Order的目的。
UPDATE /*+HINT Leading(t1 target) */ target SET b=t1.b+1 FROM t1 WHERE t1.a=target.a;
執(zhí)行計劃對比
未開啟Hint的執(zhí)行計劃
QUERY PLAN ----------------------------------------------------------------------------------------------- Gather (cost=0.00..52.77 rows=1000 width=1) -> Update (cost=0.00..52.76 rows=1000 width=1) -> Project (cost=0.00..11.09 rows=1000 width=32) -> Hash Join (cost=0.00..10.08 rows=1000 width=32) Hash Cond: (target.a = t1.a) -> Local Gather (cost=0.00..5.00 rows=1000 width=28) -> Seq Scan on target (cost=0.00..5.00 rows=1000 width=28) -> Hash (cost=5.01..5.01 rows=1000 width=8) -> Redistribution (cost=0.00..5.01 rows=1000 width=8) Hash Key: t1.a -> Local Gather (cost=0.00..5.00 rows=1000 width=8) -> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=8)
開啟Hint的執(zhí)行計劃
QUERY PLAN ---------------------------------------------------------------------------------------------- Gather (cost=0.00..52.77 rows=1000 width=1) -> Update (cost=0.00..52.76 rows=1000 width=1) -> Project (cost=0.00..11.09 rows=1000 width=32) -> Hash Join (cost=0.00..10.08 rows=1000 width=32) Hash Cond: (t1.a = target.a) -> Redistribution (cost=0.00..5.01 rows=1000 width=8) Hash Key: t1.a -> Local Gather (cost=0.00..5.00 rows=1000 width=8) -> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=8) -> Hash (cost=5.00..5.00 rows=1000 width=28) -> Local Gather (cost=0.00..5.00 rows=1000 width=28) -> Seq Scan on target (cost=0.00..5.00 rows=1000 width=28)
Runtime Filter Hint的使用
Hologres支持Runtime Filter,當SQL不滿足Runtime Filter的生成條件時,可以使用Hint強制生成Runtime Filter,提升查詢性能。
只有在執(zhí)行HashJoin操作時,才能使用Hint強制生成Runtime Filter。
并不是每次強制生成Runtime Filter后,都會提升查詢性能,需要根據(jù)業(yè)務(wù)情況綜合評估。
SQL示例
SELECT /*+HINT runtimefilter(t1 t2) */ * FROM t1 JOIN t2 ON t1.a = t2.a;
執(zhí)行計劃
--plan中出現(xiàn)runtime filter,說明觸發(fā)了runtime filter QUERY PLAN ----------------------------------------------------------------------------------- Gather (cost=0.00..10.13 rows=1000 width=16) -> Hash Join (cost=0.00..10.07 rows=1000 width=16) Hash Cond: (t1.a = t2.a) Runtime Filter Cond: (t1.a = t2.a) -> Redistribution (cost=0.00..5.01 rows=1000 width=8) Hash Key: t1.a -> Local Gather (cost=0.00..5.00 rows=1000 width=8) -> Seq Scan on t1 (cost=0.00..5.00 rows=1000 width=8) Runtime Filter Target Expr: t1.a -> Hash (cost=5.01..5.01 rows=1000 width=8) -> Redistribution (cost=0.00..5.01 rows=1000 width=8) Hash Key: t2.a -> Local Gather (cost=0.00..5.00 rows=1000 width=8) -> Seq Scan on t2 (cost=0.00..5.00 rows=1000 width=8)