對於不能所有放在內存中的關係的排序。就須要引入外排序,其中最經常使用的技術就是外部歸併排序。算法
外部排序分爲兩個階段函數
Phase1 - Sorting優化
對主存中的數據塊進行排序,而後將排序後的數據塊寫回磁盤。code
Phase2 - Mergingblog
將已排序的子文件合併成一個較大的文件排序
從2路歸併排序開始。來引出N路歸併排序算法索引
能夠見下圖內存
對於簡單的二路歸併。咱們有兩個buffer能夠用。一個用來放輸入進行排序獲得歸併塊。而另外一個則用來放輸出ci
下面來分析一下二路歸併的時間複雜度hash
在每個階段咱們都須要把歸併塊從磁盤中讀入。而後在寫回磁盤所以總共的I/O次數就是階段數 * 2
階段數能夠很容易的獲得爲
能夠很容易的發現上面的問題主要出如今。因爲咱們的輸入緩衝區只能放一個page。因此這致使了咱們不停的進行換入換出致使了io次數變得很是多。優化方法就是加大緩衝區大小。減小階段數。這就須要咱們歸併路數增大。
使用B buffer pages 這樣咱們的輸入緩衝區就能夠放B - 1個page。這樣咱們的階段數就能夠減小了。
若是咱們的table中已經有了B+樹索引。那麼咱們能夠利用它進行優化。
這裏有兩種狀況須要被考慮
聚簇索引
數據的物理地址順序和索引的順序是一致的。
這種方法比外部排序要好,由於它沒有額外的計算。好比不須要進行sort。不須要進行歸併。並且全部的磁盤訪問都是順序的。
非聚簇索引
數據的物理地址順序和索引的順序是不一致的。
若是是這樣的索引。就利用外部排序就好。
將多個元組摺疊爲單個標量值。有兩種實現方法
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開始是由於如今正好看到這裏。而以前忘了整理了。會在後面全部的都看完以後進行整理的。