(十) 數據庫查詢處理之排序(sorting)


1. 為什么我們需要對數據排序

  1. 可以支持對於重復元素的清除(支持DISTINCT)
  2. 可以支持GROUP BY 操作
  3. 對於關系運算中的一些運算能夠得到高效的實現

2. 引入外部排序算法

對於不能全部放在內存中的關系的排序。就需要引入外排序,其中最常用的技術就是外部歸並排序。

外部排序分為兩個階段

Phase1 - Sorting

對主存中的數據塊進行排序,然后將排序后的數據塊寫回磁盤。

Phase2 - Merging

將已排序的子文件合並成一個較大的文件

2.1 N-way 外部歸並排序

從2路歸並排序開始。來引出N路歸並排序算法

可以見下圖

對於簡單的二路歸並。我們有兩個buffer可以用。一個用來放輸入進行排序得到歸並塊。而另一個則用來放輸出

下面來分析一下二路歸並的時間復雜度

在每一個階段我們都需要把歸並塊從磁盤中讀入。然后在寫回磁盤因此總共的I/O次數就是階段數 * 2

階段數可以很容易的得到為

可以很容易的發現上面的問題主要出現在。由於我們的輸入緩沖區只能放一個page。所以這導致了我們不停的進行換入換出導致了io次數變得非常多。優化方法就是加大緩沖區大小。減少階段數。這就需要我們歸並路數增大。

使用B buffer pages 這樣我們的輸入緩沖區就可以放B - 1個page。這樣我們的階段數就可以減少了。

2.2 利用索引進行加速

如果我們的table中已經有了B+樹索引。那么我們可以利用它進行優化。

這里有兩種情況需要被考慮

  1. 聚簇索引

    數據的物理地址順序和索引的順序是一致的。

    這種方法比外部排序要好,因為它沒有額外的計算。比如不需要進行sort。不需要進行歸並。而且所有的磁盤訪問都是順序的。

  2. 非聚簇索引

    數據的物理地址順序和索引的順序是不一致的。

如果是這樣的索引。就利用外部排序就好。

2.3 AGGREGATIONS

將多個元組折疊為單個標量值。有兩種實現方法

1. 排序

排序之后相同的元素就會在排在一起。這樣就可以去除冗余元素

2. hash

但是如果我們不要求數據是有序的。這樣我們排序就相當於浪費了時間。因為排序起碼要花費nlogn的時間。比如GROUP BY
DISTINCT操作。在這種情況下。hashing就是一個更好的選擇

1. Partition

假設我們有B buffers。其中B - 1個buffer用來partitions而1個buffer用來存儲輸出data。

第一階段就是利用一個hash函數。把tuple哈希到不同的桶中。

2. Rehash

由於階段1之后。擁有相同cid值的tuple都被映射到了相同的桶內。這個階段我們對不同的桶在進行一次hash。就可以完成我們的去重操作。

當然利用hash操作不僅可以進行去重還可以進行其他的操作。如MAX、MIN、AVG、COUNT、SUM等

下面這張圖演示了count操作和sum操作。

這張圖演示了avg操作就是利用 sum / count

這個算是結合cmu15-445課程和對應的教材、ppt進行的總結。順序從10開始是因為現在正好看到這里。而之前忘了整理了。會在后面所有的都看完之后進行整理的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM