預(yù)計(jì)算和緩存是計(jì)算機(jī)領(lǐng)域提高性能以及降低成本的最常見的手段之一。對(duì)于那些經(jīng)常重復(fù)的請(qǐng)求,如果可以通過緩存回答,比重新計(jì)算結(jié)果或從速度較慢的數(shù)據(jù)存儲(chǔ)中讀取要快得多,消耗更少的系統(tǒng)資源。在數(shù)據(jù)庫領(lǐng)域中,物化視圖是預(yù)計(jì)算和緩存的自然體現(xiàn)。
本文主要介紹什么是物化視圖,以及如何實(shí)現(xiàn)基于物化視圖的查詢改寫。
在第一部分,我們會(huì)簡單介紹物化視圖,并介紹基于物化視圖的查詢改寫的用途。在第二部分,我們將介紹查詢優(yōu)化器使用物化視圖進(jìn)行查詢改寫的匹配和改寫過程。最后,我們將介紹查詢改寫的幾種實(shí)現(xiàn)方式,及其優(yōu)缺點(diǎn)。
背景介紹物化視圖
物化視圖是將查詢結(jié)果預(yù)先計(jì)算并存儲(chǔ)的一張?zhí)厥獾谋怼?#34;物化"(Materialized)這個(gè)詞是相對(duì)于普通視圖而言。普通視圖較普通的表提供了易用性和靈活性,但無法加快數(shù)據(jù)訪問的速度。物化視圖像是視圖的緩存,它不是在運(yùn)行時(shí)構(gòu)建和計(jì)算數(shù)據(jù)集,而是在創(chuàng)建的時(shí)候預(yù)先計(jì)算、存儲(chǔ)和優(yōu)化數(shù)據(jù)訪問,并自動(dòng)刷新來保證數(shù)據(jù)的實(shí)時(shí)性。
對(duì)于數(shù)據(jù)倉庫,物化視圖最重要的功能就是查詢加速。數(shù)據(jù)倉庫中存在大量在大型表上執(zhí)行復(fù)雜的查詢,這些查詢會(huì)消耗大量資源和時(shí)間。物化視圖可以通過預(yù)計(jì)算的結(jié)果回答查詢,消除昂貴的聯(lián)接和聚合所帶來的開銷,大幅度改善查詢處理時(shí)間,降低系統(tǒng)負(fù)載。對(duì)于可以預(yù)見并反復(fù)使用相同子查詢結(jié)果的查詢,物化視圖特別有用。
為了實(shí)現(xiàn)物化視圖的潛力,需要解決三個(gè)問題:
物化視圖選擇:選擇哪些查詢和表構(gòu)建物化視圖;物化視圖維護(hù):減少物化視圖更新成本和時(shí)間;物化視圖運(yùn)用:如何使用物化視圖加速查詢。本文主要從查詢優(yōu)化器的角度,介紹使用物化視圖加速查詢背后的技術(shù)實(shí)現(xiàn)。
基于物化視圖的查詢改寫
直接查詢物化視圖可以大幅度改善查詢處理時(shí)間,但是需要用戶修改查詢語句。使用物化視圖加速查詢的一個(gè)重要問題是,如何采用一種系統(tǒng)化和自動(dòng)化的***,自動(dòng)使用物化視圖回答查詢。通過這種透明改寫,物化視圖可以像索引一樣添加或刪除,而不會(huì)影響已有SQL。
查詢改寫使得物化視圖具有廣泛的用途:
物化視圖可以透明地改寫查詢,無需改造業(yè)務(wù)就能使用物化加速查詢;方便地應(yīng)用緩存公共結(jié)果集,以及預(yù)計(jì)算等跨查詢優(yōu)化手段;對(duì)于數(shù)據(jù)倉庫,數(shù)據(jù)集成場景,物化視圖可以物化外表結(jié)果,屏蔽多個(gè)數(shù)據(jù)源的差異,實(shí)現(xiàn)本地副本或讀寫分離;查詢改寫結(jié)合自動(dòng)構(gòu)建物化視圖,實(shí)現(xiàn)數(shù)據(jù)庫自治加速。查詢改寫的問題定義
為了實(shí)現(xiàn)更大范圍的改寫,查詢改寫通常被集成在優(yōu)化器規(guī)則中。這有幾個(gè)方面的好處。
首先查詢改寫可以利用優(yōu)化器其他規(guī)則。依靠優(yōu)化器其他規(guī)則將查詢轉(zhuǎn)換成標(biāo)準(zhǔn)和統(tǒng)一的形式,簡化匹配流程,增加改寫范圍。其中比較重要的規(guī)則是列消除,謂詞下推,解關(guān)聯(lián)子查詢等。解關(guān)聯(lián)子查詢規(guī)則允許物化視圖對(duì)包含關(guān)聯(lián)子查詢的查詢進(jìn)行改寫加速。
其次,優(yōu)化器可以遞歸每一個(gè)子樹能否被某個(gè)視圖進(jìn)行改寫。每個(gè)相關(guān)視圖都會(huì)對(duì)每個(gè)子樹產(chǎn)生多次改寫,一個(gè)查詢語句不同部分可能被不同的視圖改寫。最終所有的改寫都進(jìn)入基于成本的選擇器中,與原始查詢一起選出最優(yōu)的查詢計(jì)劃。
查詢改寫算法只需要考慮給定的查詢表達(dá)式和視圖,判斷這個(gè)查詢表達(dá)式能否從視圖中計(jì)算出來,然后從視圖上構(gòu)造一個(gè)等價(jià)的補(bǔ)償表達(dá)式,與原查詢表達(dá)式等價(jià)。查詢改寫的范圍應(yīng)該盡可能大,查詢改寫的目標(biāo)是使用少量物化視圖改寫大量查詢。最終由優(yōu)化器選擇出一個(gè)最優(yōu)的查詢計(jì)劃。
查詢改寫檢查優(yōu)化器通過多種方式來改寫查詢。最簡單的一種情況是物化視圖的查詢與查詢完全匹配,符合這種查詢重寫類型的查詢數(shù)量很少。為了進(jìn)行更通用的匹配,優(yōu)化器會(huì)嘗試使用各種規(guī)則構(gòu)造一個(gè)等價(jià)表達(dá)式改寫查詢。
查詢改寫檢查包含兩個(gè)步驟,改寫匹配檢查和構(gòu)建等價(jià)表達(dá)式。一個(gè)查詢能被視圖回答需要滿足下面兩個(gè)條件:
物化視圖Join關(guān)系在查詢中存在物化視圖有足夠的數(shù)據(jù)來回答查詢部分條件下即使不滿足條件,視圖也可能會(huì)被用于改寫。例如視圖包含一部分查詢所需要的數(shù)據(jù),可以使用物化視圖回答部分查詢,剩下的數(shù)據(jù)從原始數(shù)據(jù)中計(jì)算。這部分改寫檢查會(huì)放在高級(jí)改寫規(guī)則中進(jìn)行介紹。
具體來說改寫檢查會(huì)依次進(jìn)行Join檢查和Ouput檢查,如果查詢或視圖中含有GroupingBy和Aggregation,還會(huì)進(jìn)行額外的檢查,如果需要,會(huì)嘗試對(duì)視圖進(jìn)一步聚合。
Join檢查
當(dāng)查詢和視圖的表的Join關(guān)系相同時(shí),視圖才可能包含查詢需要的所有的行和列。一種簡單的方式是只考慮沒有子查詢的InnerJoin,這時(shí)只用比較查詢表和數(shù)量是否完全一致即可。或者通過一系列規(guī)則檢查查詢和視圖的關(guān)系代數(shù)樹包含的Join關(guān)系是等價(jià)的。更通用的一種***是構(gòu)建JoinGraph。JoinGrpah是一個(gè)以關(guān)系為結(jié)點(diǎn),聯(lián)接為邊的圖。InnerJoin的條件表示為無向邊,OuterJoin的條件表示為有向邊。JoinGraph由查詢關(guān)系代數(shù)樹構(gòu)建而來,通過比較JoinGraph就可以檢查物化視圖和查詢包含相同的Join關(guān)系。
例如對(duì)于下面的查詢
selectc_custkey,c_name,l_orderkey,l_partkey,l_quantityfrom(selectl_orderkey,l_partkey,l_quantityfromlineitemwherel_orderkey<1000andl_shipdate=l_commitdate)subqueryjoinordersonsubquery.l_orderkey=o_orderkeyleftjoincustomerono_custkey=c_custkey對(duì)于物化視圖
creatematerializedviewmview1enablequeryrewriteasselect*fromlineitemjoincustomerOnsubquery.l_orderkey=o_orderkeyleftouterjoinordersOno_custkey=c_custkey查詢和物化視圖具有相同的Join關(guān)系,查詢可以被改寫
selectc_custkey,c_name,l_orderkey,l_partkey,l_quantityfrommview1wherel_orderkey<1000andl_shipdate=l_commitdateOutput檢查
Ouput檢查保證物化視圖有足夠的數(shù)據(jù)回答查詢,這包括3個(gè)步驟:
驗(yàn)證查詢所有輸出需要的列能夠從視圖中計(jì)算出來優(yōu)化器需要檢查視圖包含查詢所有需要的行數(shù),也就是視圖的謂詞的范圍大于查詢的范圍補(bǔ)償謂詞能否從視圖中計(jì)算得來等價(jià)關(guān)系
查詢改寫能夠通過查詢中的等價(jià)關(guān)系擴(kuò)展改寫的范圍。因?yàn)榈戎禇l件具有傳遞性,等價(jià)關(guān)系可以從等值條件或者代數(shù)關(guān)系推導(dǎo)而來。例如可以從A=date_format(now(),'%Y%m%D')和B=date_format(now(),'%Y%m%D'),因?yàn)楹瘮?shù)是確定性的,可以得到A=B,如果我們還有innerjoin的條件B=C,可以進(jìn)一步得到A=B=C。
可能會(huì)有某些其他的條件可以推導(dǎo)出等價(jià)關(guān)系,例如可以從A=2,B=3,C=5推導(dǎo)出C=A+B。相比等值關(guān)系,尋找這種關(guān)系會(huì)使搜索過程更加復(fù)雜,而且我們無法實(shí)現(xiàn)所有的可能的相等關(guān)系,因此很少考慮這樣的表達(dá)式。等價(jià)關(guān)系推導(dǎo)只搜索等值條件,即使可能錯(cuò)過一些改寫機(jī)會(huì),這樣的淺層搜索可以保證速度。
表達(dá)式檢查
為了確保查詢輸出的列和補(bǔ)償謂詞需要的列都能從視圖中計(jì)算出來,我們需要一種***確定來自查詢的表達(dá)式是否和視圖中的表達(dá)式相等,或者能從中計(jì)算出來。表達(dá)式檢查無法純粹從語法上實(shí)現(xiàn),兩個(gè)表達(dá)式或者符號(hào)的文本相同,并不說明他們關(guān)系相等。例如別名的存在就會(huì)破壞基于語法的檢查。
表達(dá)式檢查需要通過等價(jià)關(guān)系和表的對(duì)應(yīng)關(guān)系推導(dǎo)而來。如果視圖和查詢中所有的表都是唯一的,那么來自同一個(gè)表的列是等價(jià)的;如果視圖和查詢中有表出現(xiàn)多次,即selfjoin,那么查詢到視圖的表的映射就存在多種可能,每種可能都需要進(jìn)行一次改寫嘗試。有了視圖和查詢之間列的對(duì)應(yīng)關(guān)系和上一節(jié)的等價(jià)關(guān)系,通過代數(shù)系統(tǒng)確定來自查詢的表達(dá)式是否和視圖中的表達(dá)式相等,或者能否從中計(jì)算出來。
存在一些啟發(fā)式的規(guī)則,允許一個(gè)表達(dá)式從另外的表達(dá)式中計(jì)算出來。比如算數(shù)規(guī)則從x+1中計(jì)算出x,例如SUM(x)和COUNT(x)計(jì)算出AVG(x),還存在一些FunctionDependency規(guī)則,例如時(shí)間函數(shù),可以通過返回的天的結(jié)果計(jì)算年等。
謂詞檢查
視圖改寫需要物化視圖中存在查詢所有需要的行數(shù),即視圖的謂詞的范圍大于或等于查詢的范圍。使用Wq表示查詢的謂詞,Wv表示視圖的謂詞,我們需要檢查Wq=>Wv,其中=>表示W(wǎng)q滿足Wv的含義。
優(yōu)化器提取所有的謂詞,并將他們轉(zhuǎn)換為CNF的形式,即W=P1^P2^...^Pn。將謂詞按照等值謂詞,范圍謂詞和剩余謂詞進(jìn)一步分為W=PE^PR^PU。PE,PR,PU分別代表等值謂詞,范圍謂詞和剩余謂詞。謂詞檢查變成了PEq^PRq^PUq=>PEv^PRv^PUv,由于正交的性質(zhì),最終將問題分解成PEq=>PEv,PEq^PRq=>PRv,PEq^PUq=>PUv三類檢查。
查詢的等值謂詞用于推導(dǎo)等價(jià)關(guān)系。查詢中任何視圖不滿足等價(jià)關(guān)系的謂詞都構(gòu)成補(bǔ)償謂詞,視圖中存在查詢無法滿足的等價(jià)關(guān)系則無法改寫。
范圍謂詞在優(yōu)化器中可以存儲(chǔ)為范圍的形式,可以方便的計(jì)算差集。對(duì)于查詢中每一個(gè)范圍謂詞,如果視圖存在對(duì)應(yīng)的范圍精準(zhǔn)匹配,不需要進(jìn)行補(bǔ)償,否則視圖范圍必須大于查詢的范圍,并通過差集構(gòu)造一個(gè)補(bǔ)償謂詞。
查詢表達(dá)式和試圖剩余的謂詞共同構(gòu)成剩余謂詞PE,只能進(jìn)行精準(zhǔn)匹配。查詢中任何與視圖不匹配的謂詞都構(gòu)成補(bǔ)償謂詞。查詢與視圖不匹配則無法改寫。
所有的補(bǔ)償謂詞都需要通過表達(dá)式檢查,確保可以從視圖的輸出中計(jì)算出來。
例如查詢
selectl_orderkey,o_custkey,l_partkey,l_quantity*l_extendedpricefromlineitem,orders,partwherel_orderkey=o_orderkeyandl_partkey=p_partkeyandl_partkey>=150andl_partkey<=160ando_custkey=123ando_orderdate=l_shipdateandp_namelike‘%abc%’andl_quantity*l_extendedprice>100物化視圖
creatematerializedviewmview2EnableQueryRewriteasselectl_orderkey,o_custkey,l_partkey,l_shipdate,o_orderdate,l_quantity*l_extendedpriceasgross_revenuefromlineitem,orders,partwherel_orderkey=o_orderkeyandl_partkey=p_partkeyandp_partkey>=150ando_custkey>=50ando_custkey<=500andp_namelike‘%abc%’查詢可以被改寫為
selectl_orderkey,o_custkey,l_partkey,gross_revenuefrommview2wherel_partkey<=160ando_custkey=123ando_orderdate=l_shipdateandgross_revenue>100Grouping和Aggregation檢查
如果視圖和查詢帶有GroupBy或Aggregation函數(shù),需要進(jìn)行額外檢查:
檢查查詢請(qǐng)求的數(shù)據(jù)分組是否與物化視圖中存儲(chǔ)的數(shù)據(jù)分組相同,如果不同,優(yōu)化器會(huì)嘗試對(duì)物化視圖進(jìn)行匯總。如果需要進(jìn)一步匯總計(jì)算,所有需要的列的都可以從視圖輸出中計(jì)算出來。例如查詢
selectc_nationkey,sum(l_quantity*l_extendedprice)fromlineitem,orders,customerwherel_orderkey=o_orderkeyando_custkey=c_custkeygroupbyc_nationkey物化視圖
creatematerializedviewmview3enableQueryrewriteasselecto_custkey,count_big(*)ascnt,sum(l_quantity*l_extendedprice)asrevenuefromlineitem,orderswherel_orderkey=o_orderkeygroupbyo_custkey查詢可以被改寫為
selectc_nationkey,sum(revenue)fromcustomerjoinmview3onc_custkey=o_custkeygroupbyc_nationkey如果分組列表不同,只能改寫GroupBy在查詢最外部的情況,否則無法進(jìn)行進(jìn)一步聚合,無法滿足第二個(gè)改寫要求。只有特定的聚合函數(shù)支持進(jìn)一步聚合,常見的聚合函數(shù)有MIN,MAX,SUM,COUNT。
例如如下查詢
selecto_custkey,count(*)ascnt,sum(l_quantity*l_extendedprice)asrevenuefromlineitem,orderswherel_orderkey=o_orderkeygroupbyo_custkey物化視圖
creatematerializedviewmview4enableQueryrewriteasselecto_custkey,l_partkey,count(*)ascnt,sum(l_quantity*l_extendedprice)asrevenuefromlineitem,orderswherel_orderkey=o_orderkeygroupbyo_custkey,l_partkey可以被改寫為
selectc_nationkey,sum(cnt)ascnt,sum(revenue)asrevenuefrommview4wherec_custkey=o_custkeygroupbyo_custkey如果聚合函數(shù)在視圖中不存在,可以通過一些規(guī)則進(jìn)行計(jì)算,例如從SUM(x)和COUNT(x)計(jì)算出AVG(x),從SUM(x)+SUM(y)中計(jì)算出SUM(x+y),這些依賴表達(dá)式改寫檢查中啟發(fā)式的規(guī)則。
高級(jí)改寫規(guī)則如果物化視圖和查詢不滿足上一節(jié)的改寫規(guī)則,還可以通過其他規(guī)則進(jìn)行轉(zhuǎn)換。
Join補(bǔ)償
如果只考慮InnerJoin,視圖和查詢的Join關(guān)系不一致有兩種情況:查詢比視圖包含更多的聯(lián)接,或者視圖包含更多的聯(lián)接。
如果查詢比視圖包含更多的表,我們可以簡單把缺少的Join添加在視圖之上,使其滿足改寫要求。Join條件會(huì)通過謂詞改寫正確的添加進(jìn)來,優(yōu)化器也可以通過后續(xù)規(guī)則調(diào)整計(jì)劃。
Join補(bǔ)償使優(yōu)化器可以更早的進(jìn)行匹配改寫,減少改寫的嘗試次數(shù)。
例如如下查詢
selectc_custkey,c_name,l_orderkey,l_partkey,l_quantityFromlineitem,customer,ordersWherel_orderkey=o_orderkeyAndo_custkey=c_custkeyWherel_orderkeybetween1000and1500Andl_shipdate=l_commitdate物化視圖
Creatematerializedviewmview5EnablequeryrewriteasSelectl_orderkey,l_partkey,l_quantityFromlineitem,ordersWherel_orderkey=o_orderkeyAndo_orderkey>=500可以被改寫為
Selectl_orderkey,l_partkey,l_quantityFrommview5joincustomerono_custkey=c_custkeyWherel_orderkeybetween1000and1500Andl_shipdate=l_commitdateJoin消除
如果一個(gè)Join出現(xiàn)在視圖中但是沒有出現(xiàn)在查詢中,可以嘗試使用Join消除規(guī)則。Join消除是優(yōu)化器優(yōu)化中的一項(xiàng)常見***,如果Join滿足以下5個(gè)條件,則表T1在與表T2的聯(lián)接中時(shí)不變的:
聯(lián)接條件是一個(gè)簡單的等值條件T1.fk是T2.pk的外鍵T1.fk滿足非null約束T2沒有任何的謂詞T2在與T1以外的表的聯(lián)接是不變的這意味著表T1在與T2的Join關(guān)系不會(huì)影響T1的結(jié)果,視圖中的T2可以在JoinGraph中忽略。不變聯(lián)接的存在允許在基礎(chǔ)物化視圖上創(chuàng)建更大的并集或超集,從而允許物化視圖包含更大的預(yù)計(jì)算,也可以改寫更多的查詢。
例如查詢
Selectl_orderkey,l_partkey,l_quantityFromlineitemWherel_orderkeybetween1000and1500Andl_shipdate=l_commitdate物化視圖
Creatematerializedviewmview6EnablequeryrewriteasSelectc_custkey,c_name,l_orderkey,l_partkey,l_quantityFromlineitem,orders,customerWherel_orderkey=o_orderkeyAndo_custkey=c_custkeyAndo_orderkey>=500可以被改寫成
selectl_orderkey,l_partkey,l_quantityfrommview6wherel_orderkeybetween1000and1500andl_shipdate=l_commitdateJoin派生
如果存在OuterJoin,視圖和查詢Join關(guān)系不一致,可以嘗試?yán)肑oin派生性,從物化視圖中的聯(lián)接重新計(jì)算查詢中的聯(lián)接。例如,能從物化視圖中的leftOuterJoin的結(jié)果里,計(jì)算InnerJoin,AntiJoin的結(jié)果,InnerJoin又能進(jìn)一步計(jì)算SemiJoin,這樣就能使用物化視圖過濾某些行來回答不同具有不同Join關(guān)系的查詢。
Join派生可以擴(kuò)展改寫的范圍,允許優(yōu)化器將基于物化視圖的改寫與解關(guān)聯(lián)的規(guī)則規(guī)則結(jié)合,改寫帶有IN,EXISTS等的查詢,也可以避免其他優(yōu)化規(guī)則對(duì)Join的調(diào)整,例如EliminateOuterJoin和PredicatePushDown可能會(huì)將outerjoin優(yōu)化成innerjoin。
Union改寫
物化視圖只包含一部分查詢所需的數(shù)據(jù),也可以用于查詢改寫。在很多場景下,物化視圖不會(huì)也無法存儲(chǔ)全部的數(shù)據(jù)。
一個(gè)典型的情況是,數(shù)據(jù)在不斷的寫入,但是寫入只發(fā)生在最近一段時(shí)間內(nèi)。在持續(xù)刷新的表上構(gòu)建全量物化視圖,這可能導(dǎo)致因?yàn)閿?shù)據(jù)插入視圖頻繁刷新,產(chǎn)生高昂的刷新成本,甚至視圖因?yàn)槌掷m(xù)刷新而完全不可用。更好的做法是構(gòu)建一個(gè)T+1條件刷新的物化視圖,存儲(chǔ)不變的數(shù)據(jù),可以降低刷新成本。
另一種常見的情況是,數(shù)據(jù)倉庫存儲(chǔ)全量的數(shù)據(jù),而查詢集中在最近幾個(gè)月的數(shù)據(jù),構(gòu)建全部數(shù)據(jù)的物化視圖成本過于高昂,物化視圖只構(gòu)建最近幾個(gè)月數(shù)據(jù),也能改寫絕大多數(shù)查詢。
Union改寫會(huì)嘗試使用視圖回答部分查詢,減少查詢中實(shí)時(shí)計(jì)算的數(shù)據(jù)量。Union改寫可以進(jìn)一步應(yīng)用Aggregation改寫,支持使用物化視圖部分?jǐn)?shù)據(jù)回答聚合查詢。
例如查詢
selectl_orderkey,l_partkey,l_quantityfromlineitemwherel_orderkeyl_orderkey>500andl_orderkey<=1500andl_shipdate=l_commitdate物化視圖
creatematerializedviewmview8enablequeryrewriteasselectl_orderkey,l_partkey,l_quantityfromlineitemwherel_orderkey>1000andl_shipdate=l_commitdate改寫結(jié)果
selectl_orderkey,l_partkey,l_quantityfromlineitemwherel_orderkey>500andl_orderkey<=1000andl_shipdate=l_commitdateunionselecto.shippriorityfrommview8wherel_orderkey>1000andl_orderkey<=1500查詢改寫的實(shí)現(xiàn)視圖改寫通常有三種查詢改寫的實(shí)現(xiàn)方式:
基于語法的改寫基于規(guī)則的改寫基于結(jié)構(gòu)的改寫基于語法的改寫
文本匹配或者語法匹配是最簡單的改寫***,將查詢的文本與物化視圖的文本或語法樹進(jìn)行比較,完全匹配可以進(jìn)行改寫。這種改寫只能匹配完整的查詢語句或子語句,細(xì)微的變化就會(huì)導(dǎo)致查詢無法改寫,適用的范圍很小。基于語法的改寫雖然簡單,但是效率很高,改寫的成本可以忽略不計(jì)。
基于規(guī)則的改寫
基于規(guī)則的改寫和其他優(yōu)化器規(guī)則相同,針對(duì)不同Pattern的查詢和視圖編寫不同的規(guī)則,尋找等價(jià)的替代關(guān)系樹。
最簡單的一條規(guī)則就是直接比較子查詢和視圖的計(jì)劃,如果相同就能改寫。高級(jí)的改寫規(guī)則不需要物化視圖等同于被替換的計(jì)劃,會(huì)嘗試計(jì)算補(bǔ)償謂詞,構(gòu)建等價(jià)查詢表達(dá)式。例如Join改寫,比較Join查詢的子表達(dá)式是否和視圖Join的某個(gè)子表達(dá)相同或者能否從中計(jì)算出來,每一個(gè)Join子表達(dá)式都存在映射關(guān)系,最后檢查補(bǔ)償表達(dá)式能否從視圖中計(jì)算得到。
基于規(guī)則的改寫可以實(shí)現(xiàn)大量重寫,實(shí)現(xiàn)也比較簡單,改寫匹配速度快,但是也存在局限性。這種改寫依賴轉(zhuǎn)換規(guī)則來尋找等價(jià)關(guān)系,因此需要窮舉所有可能的轉(zhuǎn)換關(guān)系來實(shí)現(xiàn)復(fù)雜視圖的重寫。一些復(fù)雜的視圖不可能窮舉所有的等價(jià)關(guān)系,例如存在很多的Join聯(lián)接或者復(fù)雜的Project關(guān)系,基于規(guī)則的改寫適用的范圍取決于規(guī)則的數(shù)量。
基于結(jié)構(gòu)的改寫
基于結(jié)構(gòu)的改寫與基于規(guī)則的改寫相反,通過提取查詢中的特征,使用一套規(guī)則進(jìn)行匹配改寫。優(yōu)化器將查詢表示為SPJG標(biāo)準(zhǔn)形式(Join-Select-Project-GroupBy),提取查詢中的Join,Projects,F(xiàn)ilters,Grouping和Aggregations五種表達(dá)式,分別與物化視圖對(duì)應(yīng)的表達(dá)式進(jìn)行匹配和改寫。
這個(gè)***是由微軟在2001年SIGMOD論文《Optimizingqueriesusingmaterializedviews:Apractical,scalablesolution》系統(tǒng)化的提出。這種***可以改寫包含可以改寫包含Join,F(xiàn)ilter,Project的任意查詢的***,運(yùn)用一系列的步驟匹配并得到補(bǔ)償表達(dá)式。還可以進(jìn)一步改寫含有Aggreagtion的查詢,在需要時(shí)添加Aggregation節(jié)點(diǎn)返回進(jìn)一步匯總的結(jié)果。
基于結(jié)構(gòu)的改寫很容易擴(kuò)展,例如改寫OuterJoin和子查詢等,可以完成幾乎全部的改寫。但是搜索成本較高,尤其是在查詢復(fù)雜,改寫嘗試次數(shù)很多的情況下。
參考資料
GoldsteinJ,LarsonP?.Optimizingqueriesusingmaterializedviews:apractical,scalablesolution[J].ACMSIGMODRecord,2001,30(2):331-342.BelloRG,DiasK,DowningA,etal.MaterializedviewsinOracle[C]//VLDB.1998,98:24-27.ZhouJ,LarsonPA,GoldsteinJ,etal.Dynamicmaterializedviews[C]//2007IEEE23rdInternationalConferenceonDataEngineering.IEEE,2007:526-535.JindalA,QiaoS,PatelH,etal.Computationreusein***yticsjobserviceatmicrosoft[C]//Proceedingsofthe2018InternationalConferenceonManagementofData.2018:191-203.Calcite:MaterializedView.Oracle:DatabaseDataWarehousingGuide:AdvancedQueryRewriteforMaterializedViews.Redshift:Automaticqueryrewritingtousematerializedviews.Snowflake:CreatingandWorkingWithMaterializedViews.作者:阿里云數(shù)據(jù)庫OLAP產(chǎn)品部云曦
本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。