高等资料库报告.docx
- 文档编号:7201718
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:41
- 大小:47.40KB
高等资料库报告.docx
《高等资料库报告.docx》由会员分享,可在线阅读,更多相关《高等资料库报告.docx(41页珍藏版)》请在冰豆网上搜索。
高等资料库报告
高等資料庫報告
查詢處理
【QueryProcessing】
指導教授:
陳彥良教授
學生:
陳智宗修訂
系級:
資管所研一
學號:
87423015
目錄
第零章概述
對於一個特定的查詢,通常會有很多的方法來得到其結果,舉例來說,在SQL中我們可以把同一個查詢用許多方法表示,每一種方法等於是提出一個策略來得到查詢結果,而一個好的策略和一個壞的策略在執行時間上的差異可能會相當的大,我們不能期望使用者每次所給定的查詢方法都是最有效率的,所以如何將使用者所下的查詢轉換成會得到相同結果而且更有效率的查詢就變成是資料庫管理系統的責任了。
在資料庫管理系統中負責這個轉換過程的程式稱之為”最佳化處理程式”,由上段我們得知最佳化處理程式主要的工作為查詢轉換,不過這樣似乎有點模糊,仔細的說,最佳化處理程式的工作主要是先取得使用者用系統查詢語言表示的查詢,剖析查詢,將其轉換成對等的內部運算式後,再運用一些法則將運算式用較有效率且較精簡的運算式表示,並評估該查詢所需的檔案存取與計算,然後選擇最有效率的。
甚至它可以產生執行這存取與計算的程式碼,而非只是評估查詢而已。
通常會有一套軟體,軟體中包含了讓最佳化處理程式執行真正的檔案存取的檔案管理常式。
在網路模式和階層模式中,查詢最佳化絕大部份是留給應用程式的程式設計師來做,這是因為這兩個模式的資料操控語言的敘述通常是嵌在主機的程式語言中,且在缺乏完整的應用程式的知識下,要將網路或是階層的查詢轉換成相等的查詢並非是件容易的事。
然而在關連模式中查詢最佳化處理中,使用者對於資料庫的查詢,最常用到的就是SQL了,SQL比起C或COBOL等高階程式語言,有更高的”抽象層次”(HigherLevelofAbstraction),它讓使用者可以只要說明「我要什麼」(What),而不必指示「如何擷取」(How),探訪資料庫以滿足使用者請求的過程是由系統自動執行,而非由使用者指定,所以關連式系統有時也被稱之為”自動探訪系統”(automaticnavigationsystem)。
在圖一中,我們可以明顯的看出自動探訪的優點,圖中的上半部是關連式系統中的SQL敘述,僅需兩行即可讓使用者達成新增的功能,然而在下半部,則是非關連式系統所用的程式碼,遠比關連式系統複雜許多。
然而關連式系統的所有運算皆是集合間的運算,所以使得關連式系統在效能上較非關連式系統要來得差,因此查詢最佳化處理便成了關連式系統中一個很重要的課題,在本篇報告中,即是針對關連式資料庫的最佳化處理做闡述。
事實上使用”最佳化’這個字眼並不是很恰當,因為將使用者所下的查詢轉換成”最佳的”通常需要考慮許多的可行策略,考慮過程中還包括了參考資料庫的一些統計資料,若要最佳,那麼這些統計資料便要維持最新,系統要因此額外增加負擔,花費的時間,資源自然就多,也就是”成本”是極其昂貴的,所以通常我們不會對每個查詢都做”最佳化”的處理,但是我們可以保証的是,經過最佳化處理過的查詢就大部分的情況來說會比原來的查詢來得有效率,所以”最佳化”的過程似乎稱其為”改良”或”改進”會比較恰當的。
SQL敘述
INSERTINTOSP(S#,P#,QTY)
VALUE(‘S4’,‘P3’,1000);
非關連式系統之程式碼
MOVE‘S4’TOS#INS
FINDCALCS
ACCEPTS-SP-ADDRFROMS-SPCURRENCY
FINDLASTSPWITHINS-SP
whileSPfoundPERFORM
ACCEPTS-SP-ADDRFROMS-SPCURRENCY
FINDOWNERWITHINP-SP
GETP
IFP#INP<‘P3’
leaveloop
ENDIF
FINDPRIORSPWITHINS-SP
END-PERFORM
MOVE‘P3’TOP#INP
FINDCALCP
ACCEPTP-SP-ADDRFROMP-SPCURRENCY
FINDLASTSPWITHINS-SP
whileSPfoundPERFORM
ACCEPTP-SP-ADDRFROMP-SPCURRENCY
FINDOWNERWITHINS-SP
GETS
IFS#INS<‘S4’
leaveloop
END-IF
FINDPRIORSPWITHINP-SP
END-PERFORM
MOVE1000TOQTYINSP
FINDDB-KEYISS-SP-ADDR
FINDDB-KEYISP-SP-ADDR
STORESP
CONNECTSPTOS-SP
CONNECTSPTOP-SP
圖一自動探訪與人為探訪的比較
第一章資料庫的查詢處理
第一節一般的關連式資料庫管理系統架構
一個關連式資料庫管理系統一般會有如圖二的架構,由此架構圖可看出在正常運作的情況和發生錯誤重新啟動時資料庫管理系統是如何運作:
一、查詢處理模組(QueryProcessor)
查詢處理模組(QueryProcessor)負責接受並辨識使用者所下達的SQL命令,將它們解讀後轉成樹狀的內部關連式代數型式(QueryTrees),然後交給最佳化處理模組(Optimizer)。
二、最佳化處理模組(Optimizer)
最佳化處理模組(Optimizer)收到樹狀的內部關連式代數型式後,會將它做一番轉換(QueryTransformation)後,產生效率最佳或較佳,但所得結果一樣的執行順序,並參考系統目錄(SystemCatalog)中各個關連表的大小與是否有建立索引的狀況後,選擇一個最快速的存取計劃(AccessPlan),並交由交易管理模組(TransactionManager)來排程。
三、交易管理模組(TransactionManager)
交易管理模組(TransactionManager)會將不同使用者的存取計劃做一番排程,確保不會互相干擾後,交由存取方法處理模組(AccessModule)選擇其存取方式。
其間並會寫入交易記錄(TransactionLog),並且可能會寫入某些定義到系統目錄中。
四、存取方法處理模組(AccessModule)
存取方法處理模組(AccessModule)會選定其存取方法後,呼叫檔案系統(FileSystem)。
五、檔案系統(FileSystem)
檔案系統(FileSystem)會依上層的命令呼叫磁碟機驅動程式(DiskDriver)以便存入、更改資料或將資料擷取出來。
六、回復處理模組(RecoveryManager)
另外,在當機後再啟動的情況下,會有一個回復處理模組(RecoveryManager)會先參考交易記錄後,看看是否有交易由於當機而沒有做完,若有則將它們撤回(Rollback),同時看看是否有交易的結果巳經做完了,但是卻因為當機而來不及存入資料庫中,若有則將它們重新再做一次(Redo),這些動作必須指揮交易管理模組將資料庫回復成一致(Consistent)的狀態下。
圖二關連式DBMS架構
第二節查詢處理的步驟
處理一個高階查詢的步驟如下圖所示:
圖三查詢處理的步驟
三、查詢碼的產生
執行查詢的程式碼
四、執行時資料庫的處理
查詢的結果
執行的計劃
二、查詢的最佳化
查詢的中間形式
一、掃描、剖析和確認
在高階語言中的查詢
一、掃描、剖析和確認
對於使用者用高階語言所下的查詢,系統第一件要做的工作就是將其轉換成系統內部表示的格式,在產生查詢的內部格式時,剖析程式(Parser)會檢查使用者所下查詢的語法是否正確,確認出現在查詢中的欄位名稱是資料庫中關連的欄位名稱等等,如果查詢是針對景觀的話,剖析程式為了要計算景觀,會將該景觀名稱用其對應的關連代數運算式取代。
有些系統除了將高階查詢轉換為代數運算式外,還會將轉換後的代數運算式以查詢樹(QueryTree)的形式表示,以方便接下來的後續動作。
二、查詢的最佳化
在轉換為系統的內部格式後,接下來的步驟就是把這個內部格式轉換成更有執行效率的運算式。
這個轉換基本上可分為兩方面來探討:
1.定性的查詢最佳化處理(QualitativeQueryOptimization):
利用關連代數轉換式子,將使用者查詢所轉換成的關連代數運算式先行轉換成較快速的關連式代數運算式。
此一步驟與關連表的大小並無多大關係,反而與使用者所下達的查詢類型有很大的關係,它強調的重點是:
可否用更簡化或更快速的運算式來取得結果。
2.定量的查詢最佳化處理(QiantitativeQueryOptimization):
此一步驟與關連表目前的大小以及檔案的儲存方式(循序、隨機、有無索引或是雜湊)有很大的關係,因為我們會希望先將某些內含大量值組(tuple)的關連表先行過濾,以留下可能的值組,再來與其它的關連表做運算。
通常要考量的因素有:
(1)需要用到那些關連表以取得資料。
(2)這些關連表有多大,需要透過它們的索引嗎?
(3)目前有那些索引可用?
現存索引對於加速查詢處理的幫助有多大?
(4)資料是否”叢聚”(Clustering)於磁碟上?
”叢聚於磁碟上”的意思是:
「儘量將資料在邏輯上的順序與實際在磁碟中的順序保持一致;也就是在磁碟中儘量將有某種相關順序的資料擺放在一起,以減少存取資料時在磁碟機中所花的搜尋時間,增進效率。
」依據某屬性所建立的索引,如果被設定為叢聚時,則稱之為「叢聚索引」(ClusteringIndex)。
通常叢聚的對象是以主鍵為主,也就是說:
儘量將關連表中的資料依主鍵的大小順序,排放在磁碟中。
另外要注意的是:
叢聚的動作只能針對一個屬性(可以是複合屬性)為依據,在磁碟中依序擺放,所以叢聚索引最多只能有一個。
這些工作也正是圖二中的「最佳化處理模組」(Optimizer)的職責所在。
由於定性及定量的方法有許多種,因此便可能產生許多的查詢策略,所以接下來系統便要以某些方法或準則來判斷出那一個策略是較優秀的,這些方法與準則可能包括使用磁碟區塊存取次數或是利用系統目錄中的資料庫目前狀態的資訊等等(現存的索引、關連性的基數等)。
三、查詢碼的產生
這個步驟會透過查詢碼的產生器將步驟二所選擇的計劃方案轉換成實際到資料庫去執行查詢的程式碼。
這個程式碼的形式會根據系統的需求和特性的不同而可以分為兩種:
一為直譯式的(interpretedmode),另一種則是產生編譯式的(compiledmode)。
四、執行時資料庫的處理
此部份將步驟三所產生的查詢程式碼實際執行,所以會在資料庫中做存取的動作,最後執行出來的結果也就是使用者所要的資訊。
第三節使用最佳化處理程式的原因
查詢最佳化的工作如果交由人來作的話無疑是十分昂貴的,所以由資料庫管理系統來管理最佳化,不僅讓使用者在查詢時不必煩惱如何下查詢陳述的問題,同時最佳化處理程式在絕大部份的情形之下會做得比程式設計師更好。
下面是幾個使用最佳化處理程式的原因:
一、擁有更多的資訊
因為最佳化處理程式是資料庫管理系統的一個元件,所以資料庫管理系統中所擁有的豐富統計資訊就變成了它做出正確判斷的有效依據,這些統計資料如每個定義域的資料總個數、每個基本關連的tuple個數、每個基本關連表中的每個屬性的不同值個數、每個不同值出現在屬性中的次數等等,被儲存在系統目錄中。
當最佳化處理程式要做最佳化的動作時,對於要採取什麼樣的策略較有效率,便可依循這些統計資料做比較正確的判斷,而且也比較有可能選擇最有效率的實作方法,相較之下,缺乏這些資料的程式設計師如果要能做出相同的決策可能要對系統十分熟悉且十分有經驗才有可能。
二、比程式設計師更有耐心
最佳化處理程式是一個程式,它不會疲倦也不會罷工,所以對於某一個使用者所下的查詢,它可以將所有可能的策略一一檢查,直到找出最好的為止,但是如果是由程式設計師來做最佳化的工作的話,他們不太可能費盡心力找出所有可能的最佳化策略,而且基於成本上的考量,這樣的工作由人來做是十分沒效率的。
三、資源分享
因為最佳化處理程式是許多優秀的程式設計師所設計出來的,所以它包含了這些人的智慧和技術結晶,所以只要使用者使用這個程式就好像擁有一群優秀的程式設計師來幫他們做最佳化一樣,所以使用最佳化處理程式可以很容易地將這些工程師的資源有效且廉價地提供給廣大的使用者。
四、重作最佳化容易
資料庫的資料經過一段時間後,可能會被新增、修改、刪除等等,所以資料庫管理系統中目錄所存的統計資計也會產生變動,所以原本有效率的查詢策略經過一段時間後有可能會變得相當費時,這時便需要重新最佳化。
在關連式系統中,重新最佳化只要由系統的最佳化處理程式對原先的關連式查詢重新處理即可,而若是在非關連式的系統中,重新最佳化則涉及重寫程式,是很費時費力的工作,所以很可能根本不會進行重新最佳化。
第二章最佳化處理的觀念
第一節一個簡單的例子
在尚未深入地探討查詢最佳化的細節之前,我們先從一個簡單的例子來看看查詢最佳化究竟能夠達到什麼程度的改良。
我們使用的例子是著名的”供應商-原料”(suppliers-and-parts)資料庫,表一列出了這個範例中所用到關連的綱目及其範例值。
S
S#
SNAME
STATUS
CITY
S1
S2
S3
S4
S5
Smith
Jones
Blake
Clark
Adams
20
10
30
20
30
London
Paris
Paris
London
Athens
P
P#
PNAME
COLOR
WEIGHT
CITY
P1
P2
P3
P4
P5
P6
Nut
Bolt
Screw
Screw
Cam
Cog
Red
Green
Blue
Red
Blue
Red
12
17
17
14
12
19
London
Paris
Rome
London
Paris
London
SP
S#
P#
QTY
S1
S1
S1
S1
S1
S1
S2
S2
S3
S4
S4
S4
P1
P2
P3
P4
P5
P6
P1
P2
P2
P2
P4
P5
300
200
400
200
100
100
300
400
200
200
300
400
表一供應商-原料資料庫
我們所用的查詢是”取得供應原料P2的供應商名稱”,此查詢的代數運算式如下:
((SPJOINS)WHEREP#=’P2’)[SNAME]
假設此資料庫含有100個供應商(S)和10000個供貨量(SP),其中只有50筆是關於原料P2的。
如果系統”直接”計算此運算式-即不經過任何最佳化-則所發生的事件順序可能如下:
1.合併關連表SP及S(針對S#)。
這個步驟涉及讀取10000筆供貨量;讀取100供應商10000次(每筆供貨量分別讀取一次),所以是讀取100*10000次;建構一個含有10000筆合併後值組(tuples)的中間結果;並且將這10000筆合併值組寫回磁碟(在這個例子中,我們假設主記憶體中沒有空間來存放這個中間結果關連表。
)
2.限制步驟1的結果只剩原料P2的值組。
這個步驟涉及將10000筆合併後值組重新讀回記憶體中,但是產生一個僅含50筆值組的關連表,此時我們假設主記憶體中有足夠的空間可以存放這個關連表。
3.將步驟2的結果對SNAME取投影。
這個步驟產生我們想要的最終結果(最多50個值組,它們可以存放在主記憶體中。
)
下列程序的效果相當於上述程序,因為它可產生相同的最終結果,但是很明顯的,它的效率好多了:
1.限制關連表SP只剩原料P2的值組。
這個步驟涉及讀取10000值值組,但是產生一個只含50個值組的關連表。
我們假設此關連表可以儲存在主記憶體中。
2.合併步驟1的結果和關連表S(針對S#)。
這個步驟涉及擷取100個供應商(只需一次,而非每個P2供貨量一次,因為所有的P2供貨量都巳經儲存在記憶中)。
3.將步驟2的結果對SNAME取投影(和前一程序的步驟3相同)。
我們想要的最終結果(最多50個值組)儲存在主記憶體中。
上述第一種程序共需要1030000次值組I/O,而第二種程序只需10100次。
因此,很明顯的如果我們以”值組I/O的次數”作為效率度量的標準,則第二種程序的效率是第一種程序的100倍。
(當然,在實際上,主要的決定因素是儲頁(PAGE)I/O,而非值組I/O;不過目前我們不考慮這一點。
)很明顯的,我們希望系統的實作方法是採用第二種程序,而非第一種。
因此,我們可以看到,對執行演算法作一個非常簡單的修改-先做限制再作合併,而非先作合併再作限制-在效率上就會產生顯著的改良。
而且,如果關連表SP在P#上作了索引定址(indexed)或雜湊定址(hashed),便會有更顯著的改良-步驟1中所讀取的值組個數將會從10000降為50,這一次新程序的效率將會比原程序好上將近7000倍。
同樣的,對S.S#作索引定址或雜湊定址,將有助於將步驟2的值組I/O次數從100次降為50,現在此程序的效率比原始程序好上10000倍以上。
這個結果所具有的意義是,如果執行原始查詢需要3小時,則最後的版本只需要1秒左右。
當然,還有很多進一步的改良是可以達成的。
雖然這個例子很簡單,但是它應該可以說明最佳化的必要性。
而且,它也可以讓我們了解實務上可能採用的改良方法。
第二節最佳化的一般策略
前面提到最佳化的想法可以分成兩類,一類為代數的操控,它是在不考慮關連被如何儲存的情形下來做查詢的轉換,而另一類則包含了會利用到關連表如何儲存的策略,如鍵及索引等等,讓我們先看看一些屬於這兩個領域的一些主要的最佳化觀點:
一、重要的代數觀點:
1.越早執行限制越好:
因為做查詢轉換的目的就是把執行時間縮短,而縮短時間的有效方法就是讓處理的值組越少越好,所以在一個需要多個步驟來完成的查詢,我們如果越早執行限制的話,就可以讓查詢處理的值組越少,因此後續的運算也會節省許多的時間。
2把限制和卡氏積結合成一個合併:
因為處理兩個關連表的自然合併在多數情況下,其成本會比處理相同關連的卡氏積來得便宜,所以當像RS的卡氏積要繼續做限制且該限制包含了比較R和S的屬性時,則這個卡氏積和限制結合起來根本就等於合併。
而若是限制的條件僅包含R的屬性或僅包含S的屬性,則可以應用觀點1,將限制先作用在R或S,然後再做卡氏積。
3.把一連串的一元運算元結合,如限制及投影:
因為一連串的一元運算元,通常可以簡化為只剩一個一元運算元,因此可以減少許多額外的處理。
就限制來說,針對某一關連的一連串限制可以轉換成針對該關連的單一限制,而其限制條件則是把原本的限制條件用and串接起來:
σF1(σF2(E))σF1^F2(E)
就投影來說,針對某一關連的一連串投影,我們可以只保留最後一個投影:
πA1,…..,An(πB1,….,Bm(E))πA1,….,An(E)
4.尋找一個運算式中的共通子運算式:
如果一個子運算式在運算式中出現超過一次,而且其結果並非一個很大的關連,由輔助儲存體讀入的時間又遠比重新計算的時間少很多的話,那麼預先將這個子運算式計算一次然後儲存起來會將執行時間減少許多。
二、關連實際運作的觀點
5.預先正確地處理檔案:
有兩個重要的預先處理做法:
一個是排序,另一個是建立索引,這兩者都可以讓兩個有著共通值的檔案能夠被很有效率地結合起來。
如果永久性地維持索引或是將檔案保持排序好的狀態是不經濟的話,那麼也可以考慮在處理查詢中將中間結果做暫時性的索引或排序。
6.在計算前先評估選擇:
在每一次對運算的順序或是對一個二元運算元的兩個參數順序做選擇時,我們都應該先行計算每一種方法的成本。
舉例來說,處理卡氏積時,那一個參數應該放在前面,那一個要放在後面,會影響到實際檔案存取時的效率。
不過要注意的是計算這些選擇的時間如果比執行時間要來得大的話,還不如不要評估,不過大多數的情況下,考慮所有查詢實作方法的成本,會少於因為使用一個效率低落的查詢而所付出的成本。
第三節最佳化過程的四大步驟
一、把查詢轉換成內部表示法
第一個步驟就是要把使用者下的原始查詢轉換成比較適合機器處理的內部表示法,這樣可以去除查詢語言語法上的差異,並且為以後的最佳化處理步驟舖路。
有一個明顯的問題是:
內部表示法應該以那一種格式為基礎呢?
無論使用那一種格式,都應該能夠表示系統查詢語言所有可能的查詢。
而且也應該愈中性愈好,也就是不要讓以後最佳化的選擇事先有了成見。
通常所使用的內部格式是某一種抽象語法樹(abstracttree)或查詢樹(querytree)。
例如,圖四就是範例(“取得供應原料P2的供應商名稱”)的一種可能的查詢樹。
S
針對S#進行合併
限制whereP#=’P2’
對SNAME投影
SP
最終結果
圖四查詢樹的範例
然而,如果內部表示方式使用我們熟悉的格式之一-即關連式代數或關連式計算法則,對我們將比較方便。
圖四的查詢樹可以看成是這兩種格式其中之一的某一運算式的編碼版本。
為了使我們的觀念明確,此處我們假設所用的格式為關連式代數。
因此,以後我們仍將假設圖四的查詢的內部表示法是前面寫過的代數運算式:
((SPJOINS)WHEREP#=‘P2’)[SNAME]
二、轉換成標準型式(canonicalform)
在這個步驟中,最佳化處理程式會執行許多”保証比較好的”最佳化,而且和儲存資料庫中的實際值及存取路徑都無關。
重點在於,關連式語言中,通常一個查詢可以用許多的不同方式來表示。
例如,在SQL中,即使像”取得供應原料P2的供應商名稱”這麼簡單的查詢,也可以用數十種不同的方式來表達-其中還不包括簡單的改變方式,例如把條件A=B換成B=A,或者把條件pANDq換成qANDp。
而且查詢的效率也應該和使用者所使用的查詢表示方法獨立,因此,處理查詢的下一個步驟就是把內部表示法轉換成某種對等的標準式,其目的就在去除這種表面上的不同,同時能找到比原來的表示法更有效率的方法。
為了要將步驟一的輸出轉換成某一種對等但比較有效率的格式,最佳化處理程式會使用某些定義完整的轉換法則(transformationrule或transformationlaw)。
在後面我們提到這些轉換法則。
三、選擇候選的低階程序。
把查詢的內部表示法轉換成某一種比較好的標準式之後,最佳化處理程式必須決定如何來執行該標準式所代表的查詢。
在這個階段中,現存索引或其他存取路徑、儲存資料值的分佈情形、儲存資料的實際分群狀況等種種的考慮,都一一派上用場。
在第一階段和第二階段時,我們都不注意這方面的事情。
基本策略是,把查詢運算式視為一系統的”低階”運算(“low-level”operation)(合併、限制等),而其間有某種程度的相依性。
這種相依性有一個例子如下:
執行投影運算的程式碼通常會要求其輸入值組必須依照某一順序,以便進行剔除重複值組的工作,這意味著前一運算所產生的輸出值必須具有相同的順序。
現在,對於每個可能的低階運算,最佳化處理程式都會有一組事先定義好的實作程序(implementationprocedure)與之對應。
例如,會有一組程序來實作限制運算-例如其中有一種是用
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 高等 资料库 报告