1. 程式人生 > >列儲存、行儲存

列儲存、行儲存

一、定義

1.1定義

Sybase在2004年左右就推出了列儲存的Sybase IQ資料庫系統,主要用於線上分析、資料探勘等查詢密集型應用。列儲存,縮寫為DSM,相對於NSM(N-ary storage model),其主要區別在於:

DSM將所有記錄中相同欄位的資料聚合儲存;

NSM將每條記錄的所有欄位的資料聚合儲存;

其實列儲存並不是什麼新概念,早在1985年SIGMOD會議上就有文章” A decomposition storage model”對DSM(decomposition storage model)做了比較詳細的介紹,而Sybase更在2004年左右就推出了列儲存的Sybase IQ資料庫系統(見200年VLDB文章” Sybase iq multiplex - designed for analytics”),主要用於線上分析、資料探勘等查詢密集型應用。

列儲存,縮寫為DSM,相對於NSM(N-ary storage model),其主要區別在於,DSM將所有記錄中相同欄位的資料聚合儲存,而NSM將每條記錄的所有欄位的資料聚合儲存,如下圖所示:

clip_image002

列儲存有什麼優點?

就我目前比較膚淺的理解,列儲存的主要優點有兩個:

1) 每個欄位的資料聚集儲存,在查詢只需要少數幾個欄位的時候,能大大減少讀取的資料量,據C-Store, MonetDB的作者調查和分析,查詢密集型應用的特點之一就是查詢一般只關心少數幾個欄位,而相對應的,NSM中每次必須讀取整條記錄;

2) 既然是一個欄位的資料聚集儲存,那就更容易為這種聚集儲存設計更好的壓縮/解壓演算法。

列儲存適合用在什麼場合?

OLAP,資料倉庫,資料探勘等查詢密集型應用。當然,列儲存資料庫並不是說完全不能進行更新操作,其實它們的更新操作效能並不是很差,一般也夠用,但是一方面不如自己的查詢效能,另外一方面也不如Oracle這種專門搞OLTP的資料庫,所以一般就不提這個。

列儲存不適合用在什麼場合?

相對來說,不適合用在OLTP,或者更新操作,尤其是插入、刪除操作頻繁的場合。

為啥上世紀80年代就出現的概念現在又重新炒起來了呢?

2005年VLDB有篇文章(“One Size Fits All - An Idea Whose Time Has Come and Gone”),就是那個老牛M. Stonebraker寫的,明確指出,時代變了,指望一個數據庫產品就統一天下的日子已經一去不復還了。於是,這個老牛在2005年左右做了C-Store,一個列儲存的資料庫原型系統,在VLDB, SIGMOD等頂級國際會議上灌了幾桶水後,


1.2優點

列儲存的主要優點有兩個:

1) 每個欄位的資料聚集儲存,在查詢只需要少數幾個欄位的時候,能大大減少讀取的資料量,據C-Store, MonetDB的作者調查和分析,查詢密集型應用的特點之一就是查詢一般只關心少數幾個欄位,而相對應的,NSM中每次必須讀取整條記錄;

2) 既然是一個欄位的資料聚集儲存,那就更容易為這種聚集儲存設計更好的壓縮/解壓演算法。

1.3場合

列儲存適合用在什麼場合?

  OLAP,資料倉庫,資料探勘等查詢密集型應用。當然,列儲存資料庫並不是說完全不能進行更新操作,其實它們的更新操作效能並不是很差,一般也夠用,但是一方面不如自己的查詢效能,另外一方面也不如Oracle這種專門搞OLTP的資料庫,所以一般就不提這個。

列儲存不適合用在什麼場合?

相對來說,不適合用在OLTP,或者更新操作,尤其是插入、刪除操作頻繁的場合。

1.4發展史

  有篇文章(“One Size Fits All - An Idea Whose Time Has Come and Gone”),就是那個老牛M. Stonebraker寫的,明確指出,時代變了,指望一個數據庫產品就統一天下的日子已經一去不復還了。於是,這個老牛在2005年左右做了C-Store,一個列儲存的資料庫原型系統,在VLDB, SIGMOD等頂級國際會議上灌了幾桶水後,拉了一夥人出去開了個公司叫Vertica,將其商業化,專注於資料倉庫、線上分析等市場,最近貌似還挺紅火的;順便說一下,為了貫徹上面的思想,這個老牛在同一時期又做了H-Store,一個主記憶體資料庫原型系統,沒怎麼灌水就又招呼了一幫人開了個公司叫VoltDB,將其商業化,專注於聯機事務處理。

M. Stonebraker在上世紀70年代帶頭開展關係資料庫管理系統的實現工作,做出來了Ingres,其中灌水無數,從這個原型系統基礎上產生了很多商業資料庫軟體,包括 Sybase、Microsoft SQL Server、NonStop SQL、Informix 等,而所謂的最先進的開源資料庫系統PostgreSQL也是Ingres的一個後繼分支。

二、sysbase iq 列儲存介紹

Sybase IQ —— 革命性的產品。Sybase的資料倉庫方法從根本上不同於其他的關係型資料庫提供商。Sybase認為,傳統的關係型方法以及ROLAP方法效率很低,要想獲得足夠的效能,必須通過高額的成本,在額外的硬體、軟體、資源、錢、時間上進行大量投資,否則不可能達到。因此Sybase已經開發了一個新的關係型資料庫——逆向關係型資料庫可能是對此最好的解釋,它使用一個傳統的關係型結構以及類似的非常熟悉的術語,但是卻是基於列的,而非基於行的。

我們開始審視Sybase IQ時,我們正是從此點開始,Sybase對其使用列方法的好處所作的論述“相當令人信服”。然而,通過對資料倉庫不斷增加需求、迅猛增長的來自Web的資料與使用者所帶來的分析和報表(更不必提即將到來的RFID應用),以及客戶的經驗等等,我們現在可以證明,Sybase IQ提供了一個遠比那些傳統的關係型供應商更優越的方法。

2.1列儲存

不同於傳統的關係型資料庫,其資料在表中是按行儲存的,Sybase IQ是通過表中的列來儲存與訪問資料的。儘管這種方式很明顯的不太適合於交易環境,在交易環境中,一個事務與一行資料有效對應,而在查詢程序環境中,很顯然,查詢是基於特定的列來選擇的。

列方式所帶來的重要好處之一就是,由於查詢中的選擇規則是通過列來定義的,因此整個資料庫是自動索引化的。事實上,情況並不象上述的這樣簡單,Sybase IQ有各種方法支援基於列的索引,我們將在下面就此討論。

使用列方法的另一個結果就是,Sybase IQ在壓縮方面比傳統的關係型資料庫更加有效(根據Sybase所稱,效果可達5倍之好)。這個原因,無疑說,是由於同一列中的所有資料域有相同的資料型別。因此,每一列都可以為優化的效率與檢索進行壓縮。相比來講,基於行的儲存,各個不同的域擁有各不相同的資料型別,這非常適合於交易程序。在這樣的環境中,不斷變換理想的壓縮演算法是不可行的,這意味著任何壓縮都將可能是一種最低通用的規則。

基於列的方法的另一個重要優勢完全基於所有讀出的資料量。無論何時你從傳統的資料庫中訪問資料,你需要讀出完整的每一行,而不管你實際所感興趣的是哪些域。實際上,這可能意味著讀300個位元組的資料僅僅檢索20個字元的資料。但是,基於列來讀取資料,你僅僅需要讀出你想要了解的資料。當然,讀取一條單獨的記錄時,效能上的不同可以忽略,但是許多查詢需要進行全表掃描。當讀取數百萬行資料時,效能的不同就會非常顯著。

Sybase認為,Sybase IQ的列儲存天然的比普通的ROLAP方法提供更佳的效能,IQ不需要象多數競爭對手或者Sybase Adaptive Server Enterprise(ASE)一樣支援硬體的並行處理。尤其是,Sybase指出,與資料分割槽相關的問題就是需要支援硬體的並行機制。顯而易見,不論如何進行分割槽,分割槽都會帶來很多問題(更不必說額外的維護了),不過,它打開了效能改進的實質性途徑。然而,Sybase進一步闡述道,這僅僅是對基於行的方法所與生俱來的糟糕效能的一種補償機制。

Sybase有很多事實支援它的論斷,但這並不意味著Sybase避免任何形式的資料分割槽。然而,不同於水平分割槽,Sybase IQ實施的是垂直分割槽,也就是說分割槽是按照列而不是按照行進行的。該方法的優勢之一是分割槽從來不會變得不均衡,這是由於每個表中的每列都有相同數量的域。這大大降低了管理分割槽的維護需求,同時消除了資料庫的重新組織,而在分割槽變得不均衡從而開始影響效能的時候,資料庫重新組織是必需進行的。

最後,需要注意的是,Sybase IQ並沒有避免使用OLAP。對於那些希望在聚合層次下以一個相對預先定義的方式進行查詢的使用者來講,OLAP具有明顯的優勢。基於此,Sybase 支援OLAP功能屬性如排列、百分比、平均。

2.2資料壓縮

傳統的資料庫引擎不能以一種通用的方式進行資料壓縮,主要是由於存在以下三個問題:

1. 按行儲存的資料儲存方式不利於壓縮。這是因為資料(大多為二進位制資料)在以這種方式儲存時重複並不多。我們發現,按行儲存的資料,最多能有5-10%的壓縮比例;

2. 對於許多2K 和4K 的二進位制資料頁來說,為壓縮和解壓縮而增加的開銷太大;

3. 在OLTP 環境中,大量讀取和更新混雜在一起。每一次更新需要進行壓縮操作,而讀取只需解壓縮操作,大多數的資料壓縮演算法在壓縮時比解壓縮時慢4 倍。這一開銷將明顯降低OLTP 資料庫引擎的事務處理效率而使得資料壓縮的代價昂貴到幾乎不能忍受。

在資料倉庫應用中,資料壓縮可以用小得多的代價換取更大好處。其中包括減少對於儲存量的要求;增大資料吞吐量,這相當於減少查詢響應時間。

Sybase IQ 使用了資料壓縮。這是由於資料按列儲存,相鄰接的欄位值具有相同的資料型別,其二進位制值的範圍通常也要小得多,所以壓縮更容易,壓縮比更高。Sybase IQ 對按列儲存的資料通常能得到大於50%的壓縮。更大的壓縮比例,加上大頁面I/O,使得Sybase IQ在獲得查詢的優良效能的同時,減少了對於儲存空間的需求。

在傳統的資料庫中,為提高查詢效能所建立的索引佔用的磁碟空間往往需要比資料本身需要的磁碟空間多出3-10倍。而Sybase IQ 儲存資料所佔用的磁碟空間通常只是原資料檔案的40%-60%,是傳統資料庫所佔用空間的幾分之一。

Sybase IQ與傳統資料庫在資料壓縮方面的典型對比



智慧壓縮技術,與精巧的索引結構和列儲存結合,給了IQ 比其他資料庫引擎高的多的儲存效果。這將獲得更低的儲存成本與更高的效能(因為系統僅需很少的磁碟I/O讀取或寫入任何給定的資料庫塊)。

2.3索引

Sybase IQ的祕密在於其索引。隨著Sybase 客戶發現了新的分析需求,Sybase可以簡捷地建立新的索引以滿足這些需求。這種方法的奇妙之處在於為資料倉庫增加新的索引幾乎不會(即使有也是微乎其微)影響資料倉庫的架構或使用倉庫的分析型應用。在實時企業與閉環應用領域,Sybase將索引視為在TB數量級(將來)甚至PB數量級資料倉庫中獲得更高查詢效能的關鍵。今天,Sybase實際上已使用瞭如下幾種種索引機制:

2.3.1 Low Fast 索引 

這些是低基數索引,它使用一個被稱之為“代號化”的程序。使用該程序,資料被轉換為代號,然後儲存這些代號而不是資料。這對於減少冗餘資料的數量尤其有用。例如,在整個英國擁有大量客戶群的公司,將需要儲存客戶的地址。這將意味著巨大數量的重複的郡的名稱。因此,不是儲存大量的“班夫郡”的例項,例如,Sybase將會用一個數字代替每個郡的名稱。因此,由於班夫郡按照拼音排列在英國是第5個郡(排在Aberdeen,Armagh,Avon與Ayrshire之後)因此,它可能就會被設值為5。如果一個列包含一個數字值,該值自身可以用於代號化的基礎。一旦建立了代號(這是一個自動進行的程序),一個位圖索引將被建立以表示這些代號。代號化典型地應用於列資料存在有限數量的可能取值。這也是為什麼Sybase稱之為低基數索引的原因,典型的,它僅用於不同的取值個數在1500以內的域。

2.3.2 Bit-Wise索引

對於高基數的域,那些取值個數超過1500個(如金額值),Sybase使用其專利的被稱之為Bit-Wise索引.這在你希望在範圍搜尋的時候同時進行計算的情況下,尤為有用,例如,查詢銷售價格低於50歐元的貨品數量及總收入。如同點陣圖的其他變數,該方法的優勢之一就是計數(count)查詢可以直接通過讀取索引獲得答案,而無需讀取資料。

2.3.3 High Group索引

實際上,它是B-樹索引。然而,此處的原則是,使用者僅僅在幾個列有可能作為一個組來使用的情況下,尤其是高基數與低基數的聯合搜尋時,才定義這些索引。比如可能有這樣的例子,按照商店(低基數)查詢產品銷售清單與價格(高基數)。

2.3.4 Fast Projection 索引

該索引型別(預設的)就是列儲存本身。如果使用者總是打算檢索整個列的資料,則列儲存事實上意味著列可以直接對映到表或查詢中,而無需顯式的定義任何索引。這非常有用,例如在“Where”從句中。

2.3.5 Word 索引

這是一個文字索引。它基於關鍵詞或短語字串搜尋。這種型別的索引,歷史上一直沒有用於資料倉庫中。然而,它有著大量重要的市場,在這些市場上,能夠聯合定量與定性的分析非常重要。例如,在醫療橫業,醫生的診斷通常就是:筆記。為了獲取資訊,例如發病率,因此可能必須訪問這種非結構化的資料。

2.3.6 Compare索引

這個索引技術允許資料列的比較,從效果上講,類似於“if…then…else”表示式。例如,“if支出大於收入,then…”。該型別的索引對於在Web應用中實時比較尤其有用。

2.3.7 Join 索引

正如索引的名稱所示,它是為消除表連線的需要而設計的。正象大多支援索引的情況,它可能在預先已知的查詢需求下更為有用。

2.3.8 Time Analytic 索引

這為基於日期、時間、日期與時間建立索引提供了選項。需要注意的是,對於傳統的關係型資料庫,處理基於時間的查詢尤為困難。
大量擴充套件工具用以支援在各種情況下使用這些索引。這包括為減少硬碟(或記憶體——點陣圖可能存在緩衝中)需求的索引壓縮,聯合使用不同型別索引的能力,以及使用布林操作如AND與OR過濾位元佇列等。這些特性表明,Sybase IQ克服了傳統的點陣圖的缺陷,即不適合於表連線或資料聚合。Sybase IQ在最近釋出的版本中增加了一個索引顧問(Index Advisor),這一點尤其令人歡欣:這將建議管理員何時應該增加新的索引以及增加那種型別的索引。

三、行列儲存比較

將表放入儲存系統中有兩種方法,而我們絕大部分是採用行儲存的。行儲存法是將各行放入連續的物理位置,這很像傳統的記錄和檔案系統。然後由資料庫引擎根據每個查詢提取需要的列。列儲存法是將資料按照列儲存到資料庫中,與行儲存類似;

3.1基於行的儲存

基於行的儲存是將資料組織成多個行,這樣就能在一個操作中找到所有的列。這種做法的缺點是必須每次處理一整行,而不是隻處理自己需要的列。不過,這樣在處理相同實體的兩個或多個列的查詢時能夠取得更快的速度,而且可以提高更新、插入和刪除操作的速度。

基於行的儲存系統可以進行並行處理,並且不需要模仿順序檔案系統,儘管有許多產品仍然在這樣做。這種做法的缺點是,一旦確定了這種體系結構,那麼使用的程式碼就不僅僅是“老式程式碼”,甚至比像“家族的詛咒”那樣的程式碼還要難懂。

Teradata是一種非常流行的資料倉庫產品,它使用了雜湊處理,並且從一開始就具有並行處理機制。最開始的時候它是一種資料庫機,不過當前版本採用的是在標準硬體上建立虛擬機器的方式。它從設計上就總是採用並行處理方式。各結點根據實際需要彼此交談,而不是由一箇中央點來控制。全球資訊網就是採用了這種工作方式,因此對程式設計師而言,這種模型應該不會太陌生。(結點)數量將資料值儘可能均勻地分散到硬體儲存裝置中。如果結點數改變了,那麼系統會重新分佈這些資料。由於採用邏輯地址代替了人們在傳統索引模型中使用的實體地址,因此使用者根本不會看到這些過程。故障結點會對其資料進行重新定位,並將自身從系統中刪除。新結點則會從現有結點將資料傳送到其本地儲存區,刀鋒伺服器上使用了一種建立在記憶體中的模型。這裡沒有索引;資料都是儘可能多地儲存在主儲存器中,並在這裡進行掃描。

3.2基於列的儲存

基於列的訪問存在的缺點是載入速度通常比較慢,因為源資料在外部來源中是以行或者記錄的形式表示的。這樣做的優點是針對某個列中的值進行簡單查詢的速度非常快,需要的內部儲存資源最少。這表示對某個列中特定值的搜尋可以直接進入該列的儲存區,而不需要掃描整行的資料。這樣也使得資料壓縮變得更容易,因為一個列中的資料通常具有相同的資料型別。這種體系結構在處理資料倉庫使用的海量資料時沒有問題,但不適合需要進行大量以行的方式進行訪問和更新操作的聯機事物處理。就是這種資料庫之一。在由一萬億行組成的測試資料集中,輸入資料共很明顯,這是一種適合資料倉庫的技術。這種技術雖然在壓縮和快速訪問方面有優勢,但也存在插入操作複雜的缺點。

引擎也採用了一種基於列的處理方式,但是它還對值進行標記,以獲得更高的速度和更好的資料壓縮效果。它們使用一種專用的位向量方案,可以在壓縮的狀態下進行搜尋。這種技術非常適合檔案處理,但是必須將標記恢復成其原始資料值才能顯示,以及在表示式內使用。不過,在壓縮方面鼓勵將一個數據列分解成更多更詳細的列。

四、列儲存資料查詢中的連線策略選擇方法

4.1 引言

隨著計算機技術的快速發展以及資料庫系統的深入研究和廣泛應用, 人們在期望獲得巨大

資料儲存容量的同時, 對資料的檢索效率, 尤其是即席查詢和決策分析提出了更高的要求。列儲存系統將同一列資料連續儲存, 能避免在查詢中訪問無關列帶來的效能損失, 使查詢操作更有效率, 迅速成為資料庫領域的研究熱點。不少列儲存系統如C-Store[1]、Sybase[2]、MonetDB[3]等, 都證實了列儲存技術在讀優先系統上的優越性。同時研究也發現, 列儲存查詢雖然可以避免操作無關列, 但還需連線相關列並將其組織成記錄返回給使用者。查詢相關的列越多, 列之間的連線操作就越複雜。面對海量的複雜查詢, 如何使列儲存技術揚長避短, 充分利用其查詢優勢, 成為了當今列儲存領域的研究重點。查詢優化在資料庫領域一直佔有重要的地位。現有的列儲存系統通過在儲存上做改進來減少查詢中的連線開銷, 如C-Store 的“ 投影(projection)”技術[4−5]將屬於同表的幾列儲存在一起; MonetDB 的“餅乾圖(cracker map)”[6]技術在查詢時建立相關列的對映關係; PAX[7−8]將同一元組的屬性儲存在一個磁碟頁上, 以此來加速同表之間的列連線。可以看出, 列儲存技術雖然在儲存方面已有很多研究成果, 在查詢處理層的優化研究還相當少。這是由於列儲存的處理物件縮小到“列”, 使得候選查詢計劃集合規模增大, 從而增加了查詢優化本身的代價, 影響查詢的效能。然而對連線用單一的處理方式, 也無法達到查詢執行的最優效果。針對上述問題, 本文提出一種連線策略選擇方法, 首先通過簡單規則重寫查詢, 排除代價過大的計劃, 生成候選計劃樹。進而提出動態優化樹演算法, 修改候選計劃樹中節點的執行順序, 得到可被轉化為最優計劃的查詢樹。根據列儲存的特點, 查詢樹中連線節點的連線策略可歸納為兩種:序列連線與並行連線。在此基礎上構建代價估計模型進行代價估計和策略選擇, 不僅有效減少了代價估計的開銷, 也增加了列儲存查詢處理的靈活性。經分析, 本文提出的連線策略選擇方法能有效優化查詢, 使得查詢效率顯著提高。

4.2 相關工作

列儲存的概念可以追溯到20 世紀70 年代,1976 年加拿大統計局開發實現了列儲存資料庫

管理系統RAPID[9], 並在80 年代廣泛應用。隨著企業對分析型查詢需求的快速增長, 對列儲存的研究在近十年得到了提升。早期的列儲存模型有分解儲存模型(DSM)[10]、PAX 等。新的列儲存系統包括MonetDB/X100[11]、C-Store 等。研究表明,列儲存資料庫系統在分析型業務中的效能比行儲存資料庫系統性能超出多個數量級[5]。查詢優化在資料庫領域佔有重要地位。目前較為成熟的優化方法有兩類:基於規則的優化方法(rule based optimization, RBO)以及基於代價的優化方法(cost based optimization, CBO)[12−14]。基於規則的優化方法根據指定的規則或定義路徑的優先順序對邏輯計劃進行優化。基於代價的優化方法通過統計資訊和存取路徑評估所有候選計劃的代價, 選擇代價最小的一個。通常優化器選擇結合這兩種方法來進行優化[14]。然而, 在列儲存系統中的優化卻相當少, 目前的列儲存查詢處理, 都將重點放在物理儲存的改變上, 沒有統一的規則或代價的權衡。C-Store 是開源列儲存系統, 它將每列單獨儲存, 多列儲存在一個投影(projection)中, 按照其中一列排序[1,4−5]。因此C-Store 查詢經常基於一個投影, 或者含有公共排序列的不同投影, 以此減少列的連線代價。連線操作首先根據對排序列的篩選, 得到position 列表並用它過濾其他列。因此需要通過索引檢索position 的第一個值來定位其他列的起始查詢位置[4]。position 是基於排序列的, 若執行的謂詞列在任何投影中都沒有排序,則需對其進行全列掃描, 這樣代價很大。MonetDB 以(key, value)形式儲存資料, 利用“餅乾圖(cracker map)”來連線列。在多選擇列之間, 選擇某一列作為基列(左列), 跟其他相關列兩兩繫結在一起。根據左列的篩選條件進行分割槽, 並建立該分割槽的索引, 重新儲存為M(crackermap)。由於基列一樣, 使用點陣圖向量之間的位與來連線列[6]。此方法在第一次查詢的時候需要消耗大量的記憶體, 對列進行範圍的劃分以及索引的建立。在以後的查詢中, 如果基於該列的謂詞發生變化, 需重新劃分範圍並修改索引。該方法記憶體消耗巨大, 僅適用於記憶體資料庫MonetDB , 卻無法在列儲存系統上通用。上述兩個系統, C-Store 的查詢執行器相當完善, 但是查詢優化器卻未實現[4]。MonetDB 的查詢處理中, 執行計劃並不通過代價模型評估, 僅是通過啟發式規則來重寫計劃[15]。可見現有的列儲存系統連線策略單一且侷限, 在查詢優化方向的研究非常少。本文結合簡單規則和動態Huffman演算法, 建立基於代價的連線策略選擇模型, 針對不同情況處理列之間的連線。

4.3 定義

定義 1 (空間) 列儲存資料的查詢處理物件為列, 屬於一張表的列屬於同一個空間。定義 2 (rowid) 為了重組一行資料, 每一列都附加一個偽列rowid, 形如, 如圖

1.  每一列在rowid 上都存在B 樹索引。

定義 3 (連線) 同空間內由and 連線的兩個操作、兩個列的比較操作稱為同空間列的連線; 不同空間兩列間的操作稱為不同空間列的連線。定義 4 (序列連線) 一個連線操作的物件有兩個孩子操作, 用一個操作的結果通過連線條件去過濾另一個操作的方法稱為序列連線, 如圖2。定義 5 (並行連線) 先分別執行兩個相關操作,再通過連線條件得到結果的方法稱為並行連線,如圖3。

定義 6 (驅動列) 連線操作中, 兩個處理物件中較少行數的列為驅動列。它可以是原始資料,

李靜 等:列儲存資料查詢中的連線策略選擇方法 853也可以是中間結果中的列。定義 7 (被探測列) 當從驅動列得到了一項資料以後, 在該探測列中查詢符合條件的資料。

對於 SQL:select m from A, B where A.m=B.n其中m 為驅動列, 則連線策略如圖2 和圖3。

4.4 連線策略選擇方法

本文重點研究如下形式的查詢:select A from T where Λ(P1,P2 ,...,Pm) (1)

T 是查詢引用的關係集合; A 是引用關係T 的屬性集; (P1,P2 ,...,Pm)是由and 連線的謂詞。對於列儲存而言, 該查詢可轉化為如下形式:

Ci 是查詢相關的列, 如果Ck 上不存在選擇謂詞,設σ(Ck)為true。Fij 是連線條件, 如果Ci、Cj 上不存在連線謂詞, 設Fij 為true。對於n 個節點的查詢樹來說, 列之間連線方法有種。基於代價的優化連線策略就是從中選擇一個I/O 最小的計劃, 然而資料按列儲存後, n 往往很大, 這使得從中選擇一個理想計劃十分困難, 因此需要首先根據簡單的規則削減計劃的選擇範圍。

4.4.1 簡單下推規則

根據啟發式原理:由於關係越小, 所需讀寫的I/O 也就越少, 因此中間結果之和較小的計劃

很可能是較好的計劃[12]。本文根據關係代數表示式的下推規則來執行不同空間的謂詞下推; 並使用列的級聯規則合併同列選擇謂詞[12]; 最後處理列間的連線謂詞。通過以上規則得出式(2)中where 子句的形式:

定義選擇空間 T, 連線空間J:

查詢計劃如圖4, 用於連線的左深樹能和連線演算法很好地互動, 有利於形成有效的計劃[12]。

4.4.2 動態優化樹

對左深連線樹而言, 應該選用估計數值較小的節點作為左變元[12]。本文結合動態Huffman

樹[16]思想提出動態優化樹演算法, 改進查詢執行順序, 保證執行該樹的代價儘可能最小, 如圖5。(1) 利用動態Huffman 樹原理修改空間之間的連線順序。設 Tout 為每個空間根節點的輸出元組數, 查詢計劃中的選擇空間根節點Ti∈{T1,T2,…,Tn}的權值為Tiout。若存在某空間與多空間連線, 將該空間作為最左空間, 根據動態Huffman 樹原理修改該空間與其他空間的連線順序。若不存在這樣的空間, 則修改所有空間的連線順序。(2) 利用動態Huffman 樹原理, 修改空間內的連線順序。

優先處理選擇性較好的謂詞可以儘早減少需處理的元組數目, 從而避免I/O 的浪費[12]。設

C.ff 是C 列上滿足篩選條件的選擇率[17], 選擇率越小, 選擇性越好。若T 空間有n 個葉子節點, 設其權值為:C1.ff,C2.ff, …, Cn.ff. 。T 內Ci、Cj 列的連線結果權值為Ci.ff×Cj.ff, 因此動態Huffman樹演算法相當於從左至右結合最小ff 的節點。由於處理最左節點的I/O 過大會影響整體計劃的I/O,優先處理帶有索引的節點能夠有效減少整體I/O。如圖 4 所示, 當查詢到C3 列的選擇節點f3 是擁有索引的最小ff 節點, 且F2 僅是rowid 相等的連線條件時, 新建N_node 節點, 並通過1~4 步修改樹的執行順序, 刪除虛線節點。對於每個連線節點, 其連線方式可歸納為兩種:

序列連線和並行連線。若對每個節點都採用並行連線, 需考慮讀取每列資料的I/O, 開銷相當大。若都採用序列連線, 需考慮重複查詢索引塊和資料塊帶來的額外開銷, 以及沒有索引的情況下帶來的巨大I/O 浪費。因此, 有必要定義代價估計模型進行策略選擇。

4.4.3 基於列的代價估計模型

查詢計劃的連線節點有兩類:T 空間的中間節點和J 空間的葉子節點。針對這些節點的特點,本文提出一種代價估計模型:M={I, O, A}, 為每個節點決定連線策略。其中 I 是M 模型的輸入資訊, 是查詢樹節點的統計資訊。它包括:

T 空間中間節點的統計資訊node_info={Tout (A),B_info A∈T,B∈T} (7)Tout(A)是驅動列A 的篩選結果行數[17]; B_info 是被探測列的統計資訊。

其中, FF(B)為B 列上滿足條件的選擇率[17]; B(B)為容納一列B的資料塊個數; T(B)為B的行數; V(B)為B 列的基數, 即B 列上不同值的個數; Htr(B)為B 列上rowid 索引的層數; Htv(B)為B 列上value索引的層數。J 空間的葉子節點的相關統計資訊

node_info={J_info,T1_info, T2_info,Tmid_info} (9)

J_info={A_info, B_info A∈T1, B∈T2} (10)

{ } T1_info= T1out ,Columnlist (11)

{ } T2_info= T2out ,Columnlist (12)

{ , } out Tmid_info= T Columnlist (13)

其中J_info 是連線節點的資訊; T1_info 是J 的左孩子所在空間的根節點資訊, 它可以是T 空間的根節點, 也可以是J 空間的根節點; T2_info 是J的右孩子所在空間的根節點資訊; Tmid_info 是先前節點處理的T1與T2的連線結果, 由於最左葉子節點還未處理連線, 因此該項統計資訊為空;Columnlist 是相應空間內處理過的列的列表。O 是M 模型的輸出集合, 它為每個連線節點選擇代價最小的連線策略;A 是M 模型的演算法, 分別針對T 空間的中間

節點和J 空間的葉子節點給出相應的策略選擇。其中涉及的量值計算如下:

列儲存系統的每一列資料的B樹索引都是聚

簇索引。當A 為驅動列時, B 列與A 列的連線在B上所產生的磁碟I/O 為:

(1) 序列連線

① 根據 B 的索引:

對於驅動列A 中的每一條資料, 都約有B(B)/V(B)個符合條件的資料塊。

② 根據 B 的rowid:

連線代價為查詢索引塊與資料塊之和, 其中資料塊可估計為:驅動列篩選的結果最稀疏和最

密集情況的折中。

(2) 並行連線

① 全列掃描:

FS(B)= B(B) (16)

② 索引掃描:

IS(B)=Htv(B)+B(B)× FF(B)

使用後序遍歷查詢樹, 用M 模型演算法A:

Cost_Model (node_info)為節點選擇連線策略。

圖 6 演算法中2~5 行程式碼處理T 空間的中間節點, 為每個連線節點評估序列連線和並行連線的 I/O, 選取產生較小I/O 的連線方式。演算法的 6~23 行處理J 空間的最左葉子節點:

(1) T1 處理的結果包含A 列, 可確定J 與T1空間的序列連線方式。T2 包含B 列時, 可確定A、B 並行, J 與T2 序列。T2 不包含B 列時, 根據代價的權衡來決定連線方式。(2) T1 處理的結果不包含A 列, 可根據代價估計A 列與T1 列的串並行I/O, 選擇產生較小I/O的策略。接下來處理同(1)。演算法的 24~29 行鍼對J 空間的右葉子節點:(1) T1、T2 篩選結果不包括A、B 列, 且節點本身獨立執行連線的代價不大於過濾其兄弟節點的代價, 選擇並行連線。

(2) 其他情況下, 用右節點直接過濾其左兄弟節點的結果。

4.4.4 優化演算法及理論分析

至此, 本文給出列儲存資料查詢中的連線策略選擇方法的總演算法:Opt_Plan (tree), 如圖7。

該演算法對前文如(2)形式的SQL語句生成的語法樹進行優化處理, 得到優化的查詢計劃。列儲存資料查詢可生成大量的候選查詢計劃, 中間關係的估計能夠幫助選擇較優的邏輯計劃。本文用式(18)形式的SQL語句, 分析Opt_Plan演算法。相關統計資訊如表1 所示。

select , , , from ,

where and

and and

A.a A.b B.a B.c A B

A.b= 9 B.c= 8

A.c=6 A.a= B.a

同空間內 rowid 唯一, 每一個選擇條件都能減少先前操作所產生的中間結果。執行A.b=9 and B.c=8 意味著兩個空間的笛卡爾積操作, 中間元組約為7 500; 執行A.b=9 and A.c=6 產生的中間元組約為2。可見優先執行同空間內的選擇, 能儘早減少需要處理的元組。因此優化的首要步驟是利用簡單下推規則,排除代價過大的計劃。驅動列的元組數是決定連線操作I/O 的主要因素。單獨考慮A.a=B.a 節點, 將B.a 作為驅動列,序列連線需要約12 000 次I/O。將A.a 作為驅動列, 序列連線需要約7 000 次I/O。可見利用動態優化樹演算法修改執行順序, 確定左變元為驅動列是非常重要的。簡單規則和動態優化樹演算法都能有效地縮小中間結果之和, 具有最小中間結果之和的計劃可能是較好的計劃[12]。當涉及到具體執行時, 較小I/O 的計劃被認為是較優計劃, 因此對連線策略的選擇非常重要。對優化過的式(18)產生的計劃僅使用序列連線策略, 需要約245 次I/O(公式(19)); 僅使用並行連線策略, 需要約576 次I/O(公式(20)); 而M 模型評估的策略, 需要約95 次I/O(公式(21))。由於B.a 列不存在索引, 序列連線和並行連線都需要全列掃描B.a, I/O 開銷較大。

可見 M 模型能夠評估選擇最優的連線策略,本演算法能夠有效地優化查詢計劃。不僅如此, 本文演算法具有較好的可擴充套件性, 演算法思想能在開源列儲存系統上通用。以 C-Store 為例, C-Store 僅對排序列建立索引, 或者對所有列建立position 索引[4]。對於式(18)語句的A 表篩選條件來說, 若存在projection 包含A.b、A.c、A.a, 且根據A.c 排序, 則C-Store 系統上的計劃為:全列掃描A.b 列, 得到長度約為100的position; 定位A.c 列的第一個position, 抽取A.c列相應position 上符合條件的值, 得到長度約為2的position, 最後得到A.a。優化後的計劃為:索引掃描A.c, 忽略對索引塊的訪問, 可能只需要一個數據塊的I/O, 得到長度為20 的position, 過濾A.b 列, 得到長度為2 的position, 最後得到A.a。顯然, 經過優化的計劃能以更小的I/O 得到較優的查詢計劃, 可見本文提出的優化演算法思想可通用於列儲存系統。

5 總結與展望

上述提出的方法根據簡單規則過濾了代價過大的計劃, 進而提出動態生成樹演算法, 根據動

態Huffman 樹原理對候選查詢計劃樹中的查詢執行順序進行修改並最終得到可生成較優計劃的候選樹。經分析, 該步驟能減少列連線過程中的I/O 開銷。同時, 提出了基於代價的優化連線策略選擇方法, 它針對資料按列儲存後並行連線和序列連線兩種策略進行代價估計和策略的選擇, 充分利用了序列連線和並行連線各自的優勢, 為列儲存的查詢優化提出了新的策略。經分析, 本模型能以較小的時空開銷完成查詢計劃的優化。今後的工作重心將轉向對並行連線策略的進一步研究, 對適用於列儲存的雜湊連線和排序合併連線等策略進行分析優化, 使列儲存查詢計劃得到進一步的優化處理。

五、列儲存資料庫的安裝

MonetDB是一個開源的高效能列儲存資料庫系統,比基於行儲存的MySQL效能最多可提高10倍 , 參見 MonetDB的TPC-H 效能測試。 MonetDB目前仍然是一個學術機構的開源專案,差不多每6個月出一個Release,由於Bug眾多並不推薦在生產環境中使用。

關於列儲存資料庫(Column-oriented DBMS) 近年來,從商業產品(Sybase IQ)到開源的BigTable類專案(HyperTable, Hbase, Cassandra等),列儲存資料庫在OLAP應用中的地位越來越突出。

安裝步驟(CentOS 5.2 x86_64),安裝過程同時編譯了MonetDB的Java和PHP客戶端庫:

5.1預先安裝JDK, ANT和PHP

#wget http://apache.mirror.phpchina.com/ant/binaries/apache-ant-1.7.1-bin.tar.gz

將它們加入執行路徑,例如/etc/profile中加入

export JAVA_HOME=/usr/local/jdk1.6.0_06

export ANT_HOME=/usr/local/apache-ant-1.7.0

export PATH=$PATH:$JAVA_HOME/bin:$ANT_HOME/bin:/usr/local/php-fcgi/bin

配置完後,重新登入,確認相關可執行檔案的路徑:

# java -version

java version "1.6.0_06"

Java(TM) SE Runtime Environment (build 1.6.0_06-b02)

Java HotSpot(TM) 64-Bit Server VM (build 10.0-b22, mixed mode)

# javac -version

javac 1.6.0_06

# php-config

Usage: /usr/local/php-fcgi/bin/php-config [OPTION]

Options:

--prefix            [/usr/local/php-fcgi]

--includes          [-I/usr/local/php-fcgi/include/php -I/usr/local/php-fcgi/include/php/main -I/usr/local/php-fcgi/include/php/TSRM -I/usr/local/php-fcgi/include/php/Zend -I/usr/local/php-fcgi/include/php/ext -I/usr/local/php-fcgi/include/php/ext/date/lib]

--ldflags           [ -L/usr/kerberos/lib64]

--libs              [-lcrypt   -lcrypt -lrt -lldap -llber -lpng -lz -ljpeg -lcurl -lz -lresolv -lm -ldl -lnsl -lxml2 -lz -lm -lssl -lcrypto -ldl -lz -lcurl -lgssapi_krb5 -lkrb5 -