vb:SQL優(yōu)化-查詢重寫規(guī)則

1.基本規(guī)則

盡量早下推
選擇合適的連接
子查詢轉(zhuǎn)連接

參考:

https://docs.vastdata.com,cn/zh CN/VastbaseG100/V2.2.15/1/3e9f8b619dd94363b34fd5b58b14d2ab

1.1 相關(guān)概念

子查詢與子鏈接
沿用了pg的概念,在from后面叫子查詢,在其他關(guān)鍵字后面都叫子鏈接;其他系數(shù)據(jù)庫產(chǎn)品沒有區(qū)分這種概念。

子鏈接存在于什么地方?

  • select后面(目標列,target list)
  • where后面
  • having后面

我們能調(diào)的大致就如上三個方面。在from后面的子查詢?nèi)斯じ深A(yù)的較少,vb產(chǎn)品本身已經(jīng)做了較多優(yōu)化。

sublink可以分為以下幾類:

  • exist sublink:對應(yīng)EXIST、NOT EXIST語句。
  • any_sublink:對應(yīng)op ANY(select..)語句,其中OP可以是“<”、“>”、“="操作符,IN/NOT IN (select..)也屬于這一類。
  • all sublink:對應(yīng)op ALL(select..)語句,其中OP可以是“<”、“>”、“=”操作符。
  • rowcompare sublink:對應(yīng)record op(select ..)語句,行比較。
  • expr_sublink:對應(yīng)(SELECT with single targetlist item ...)語句,僅僅選擇一列。
  • array sublink:對應(yīng)ARRAY(select...)語句。
  • cte sublink:對應(yīng)with query(...)語句。

相關(guān)子鏈接、非相關(guān)子鏈接:

  • select * from t1 where t1.i1=(select t2.i1 from t2 where t2.i2 = 1 limit 1);
  • select* from t1 where t1.i1 = (select t2.i1 from t2 where t2.i2 = t1.i2 limit 1);

In-sublink(非相關(guān)子鏈接,非易變函數(shù))例子:

Exist-sublink包含相關(guān)條件: where子句中必須包含上一層查詢的表中的列,子查詢的其它部分不能含有上層查詢表中的列。
其它限制如下:
子查詢必須含有from子句。
子查詢不能含有with子句。
子查詢不能含有聚集函數(shù)。
子查詢里不能包含集合操作、排序、limit、windowagg、having操作。
子查詢不能包含易變函數(shù)。

例:


2.常用的調(diào)優(yōu)規(guī)則

2.1 lazyagg

(惰性聚合)

核心思想:
通過推遲某些聚合操作的執(zhí)行,直到進行了過濾或連接等操作之后,以此來減少計算量和提高查詢性能

場景:
基表數(shù)據(jù)量大、distinct值較多
子查詢有g(shù)roupby,關(guān)聯(lián)外表后還有g(shù)roup by
關(guān)聯(lián)字段是內(nèi)層的group by字段(或之一)

參考:

https://blog.csdn.net/devcloud/article/details/125457358

例:

2.2 magicset

核心思想:
將主查詢中的where過濾條件下推到子查詢中,實際中是把表下推,多一次關(guān)聯(lián)。
先針對子查詢的關(guān)聯(lián)字段進行關(guān)聯(lián),分組聚集,再和主查詢進行關(guān)聯(lián),減少相關(guān)子鏈接的重復(fù)掃描,提升查詢效率。

場景:
子查詢/子鏈接(=,>,<)
關(guān)聯(lián)聚合子查詢,子查詢數(shù)據(jù)量很大,條件下推大大減少數(shù)據(jù)量。
過濾條件是來自于聚合子查詢與外表連接的那個表

默認的rewrite_rule就是magicset

postgres=# show rewrite_rule ;
 rewrite_rule
--------------
 magicset
(1 row)

參考:

https://blog.csdn.net/robinson1988/article/details/139048758

例:


2.3 intargetlist

核心思想:提升targetlist中的子查詢

場景:子查詢在目標列中,有聚集函數(shù)

例:

例:

2.4 uniquecheck

核心思想:提升無agg的子鏈接語句,在執(zhí)行時檢查返回行數(shù)是否為1行。

場景:無agg的相關(guān)子鏈接(非相關(guān)子查詢不適用),每個子鏈接只有一行輸出(Unique check required)

例:

2.5 intargetlist, uniquecheck

場景:
targetlist中的無agg的子查詢

例:

2.6 enable_sublink_pullup_enhanced

核心思想:
使用增強后的sublink查詢重寫規(guī)則,包括where、having 子句的子鏈接
提升場景:where,having子句中,子查詢含聚集函數(shù)

例:

例:

2.7 qrw_inlist2join_optmode

核心思想:
控制使用inlist-to-join對SQL進行改寫

例·:

set qrw_inlist2join_optmode='rule base'
SELECT* FROM rewrite_rule_hint_t5 WHERE slot = '5' AND (name) lN
(SELECT name FROM rewrite_rule_hint_t5 WHERE sIot='5' AND cid IN (5,100,1001,1002,103,1004,1005,1006,1007,2000,4000,10781986,10880002) LIMIT 50);

其中rule base是強制轉(zhuǎn)連接,此外還有另外兩種選項:cost base、超閾值轉(zhuǎn)連接

2.8 disable_pullup_expr_sublink

核心思想:禁止表達式的子鏈接提升

例:

2.9 no_expand

核心思想:不提升子查詢
場景:
選擇率較低且可以使用索引過濾訪問頁面的子查詢,嵌套執(zhí)行不會導(dǎo)致性能下降過多,而提升之后擴大了查詢路徑的搜索范圍,可能導(dǎo)致性能變差。

例:

實際使用中no_expand因包含disable_pullup_expr_sublink的功能,所以使用的情況比disable_pullup_expr_sublink要多。

2.10 predpush、predpushnormal、predpushforce

核心思想:
predpush可以將謂詞下推到子查詢塊中

場景:
在父查詢塊中的數(shù)據(jù)量較小或子查詢(group by/distinct)中可以利用索引的場景下能夠提升性能,連接條件下推。

predpush的rewrite_rule規(guī)則有3個,分別是:

  • predpushnormal:嘗試下推謂詞到子查詢中。(常用,能下去就下去)
  • predpushforce:嘗試下推謂詞到子查詢中,盡量利用索引掃描
  • predpush:利用代價在predpushnormal和predpushforce中選擇一個最優(yōu)的分布式計劃,但是會增加優(yōu)化時間。

此外還有
predpush_same_level:同層下推,前提:set rewrite rule='predpushforce';

2.11 from_collapse_limit, join_collapse_limit

核心思想:根據(jù)生成的FROM列表的項數(shù)來判斷優(yōu)化器是否將把子查詢合并到上層查詢,如果FROM列表項個數(shù)小于等于該參數(shù)值,優(yōu)化器會將子查詢合并到上層查詢。

原理:
根據(jù)得出的列表項數(shù)來判斷優(yōu)化器是否執(zhí)行把除FULL JOINS之外的JOIN構(gòu)造重寫到FROM列表中。

SELECT * FROM table1 t1 JOlN table2 t2 ON t1.id =t2.id
JOIN (SELECT * FROM table3 t3 jOlN table4 t4 ON t3.id = t4.id) sub ON t2.id = sub.id;
  1. 解析FROM列表FROM列表包含三個部分:
    table1 t1 table2 t2 子?xùn)嗽?(SELECT* FROM table3 t3 JOlN table4 t4 ON t3.id = t4.id) sub
  2. 遞歸處理每個FROM列表項優(yōu)化器會遞歸地處理每個FROM列表項:
    對于table1 t1和table2 t2,它們是簡單的表引用,直接添加到JOIN 列表中。
    對于子?xùn)嗽僺ub,優(yōu)化器會進一步遞歸處理其內(nèi)部的FROM 列表(table3 t3 和 table4 t4)
  3. 合并子問題的結(jié)果如果子查詢的結(jié)果(sub)的長度不超過fromcollapselimit,則將其合并到當前的JOIN 列表中。
    否則,將子查詢的結(jié)果作為一個整體添加到當前的JOIN 列表中。

假設(shè)from collapse limit=8,則最終生成的JOIN 列表為:[table1 t1,table2 t2,table3 t3, table4 t4]
如果from collapse limit =3,則子查詢的結(jié)果不會被合并,最終生成的JOIN列表為:[table1t1,table2 t2,(table3 t3 JOIN table4 t4) sub]

場景:
表連接的數(shù)據(jù)比較多,超過8個。

2.12 try_vector_engine_strategy

核心思想:
使用向量化引擎

向量化執(zhí)行引擎具有以下優(yōu)點:

  • 一次一個batch,讀取更多數(shù)據(jù),節(jié)省10。
  • batch中記錄較多,CPU cache命中率提升。
  • Pipeline模式執(zhí)行,所數(shù)調(diào)用次數(shù)少。
  • 一次處理一批數(shù)據(jù),效率高。

場景:
分析類復(fù)雜查詢:如果查詢語句中包含表達式計算、多表join、聚集等操作時,通過轉(zhuǎn)換為向量化執(zhí)行能夠獲得性能提升。

2.13 rownumenhance/enable_constraint_optimization

可以將rownum<const或rownum<=const 的場景轉(zhuǎn)為 limit 常量算子
消減不必要的條件

例:

2.14 總結(jié)

3.各版本新增規(guī)則

3.1 【2.2.15版本】新增

  • 2.2.15.3
    enable_any_sublink_pullup_enhanced, 啟用此選項后計劃器會嘗試將相關(guān)子連接進行提升,生成更好的執(zhí)行計劃。(即提升any)

  • 2.2.15.4
    rewrite_rule='predpushnormal',query dop=1支持謂詞推入。

  • 2.2.15.7

enable remove unused outputs
功能描述:用于減少子查詢中不必要的目標列投影。對子查詢的目標列進行優(yōu)化,如果沒有被上層引用,滿足條件的情況下可以不進行投影,以提升效率。

3.2 【3.0.8版本】新增

    1. enablejeenhanced:
      在查詢語句中,支持對左外連接進行優(yōu)化,消除不需要的右表,提升查詢效率
SELECT DISTINCT test1_1200501.* FROM test1_1200501 LEFT JOlN test2_1200501 ON test1_1200501.id=test2_1200501.id;
    1. rewrite rule增加self_join_elimination,magicset
      自連接消除是指對多次引用同一表的連接查詢,進行對重復(fù)掃描的消除優(yōu)化
SELECT a.id, b.*FROM table_1238182 a JOlN table_1238182 b ON a.id=b.id;
    1. rewrite rule增加fkey join elimination
      當一個表(子表)通過外鍵引用另一個表(主表)的主鍵時,如果子表中的每一行都與主表中的唯一一行相匹配,那么這種一對一的主外鍵連接將被優(yōu)化器消除。
    1. rewrite_rule增加order_by_elimination:
      消除多余ORDER BY。支持場景如下:
      查詢中帶有連接操作(LEFT JOIN、INNER JOIN等),同時不含有rownum表達式,可以消除連接兩個子查詢中頂層
      的 ORDER BY 子句。
      查詢中存在集合操作(UNION ALL等),同時不包含rownum表達式,可以消除集合兩邊中頂層的ORDER BY子句。
      ORDERBY所在該層查詢中,不存在LIMIT子句,不存在DISTINCT ON子句。
      外層查詢目標列中存在聚集函數(shù),內(nèi)層查詢中的ORDER BY可以進行消除。
      如存在多層嵌套,更深層的子查詢中的ORDER BY也可以進行消除。
      子連接中(IN/EXISTS)的ORDER BY可以進行消除。

4.規(guī)則限制

4.1 限制1

4.2 限制2

參考

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容