日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CMU Database Systems - Sorting,Aggregation,Join

發(fā)布時(shí)間:2023/11/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CMU Database Systems - Sorting,Aggregation,Join 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Sorting

排序如果可在內(nèi)存里面排,用經(jīng)典的排序算法就ok,比如快排

問題在于,數(shù)據(jù)表中的的數(shù)據(jù)是很多的,沒法一下都放到內(nèi)存里面進(jìn)行排序

所以就需要用到,外排,多路并歸排序

看下最簡(jiǎn)單的,2路并歸排序,

設(shè)文件分為N個(gè)page,memory中一次最多可以放入B個(gè)pages

所以在sort過程,一次性可以載入B個(gè)page,在內(nèi)存中page內(nèi)排序,寫回disk,稱為一輪,run
那么如果一共N個(gè)page,需要N/B+1個(gè)run

在merge過程,如果雙路并歸排序,只需要用到3個(gè)page的buffer,多了也沒用

Merge過程的cost

每個(gè)pass都需要讀寫一遍所有的數(shù)據(jù),cost為2N
2 way,所以一共有1 + logN個(gè)pass

多路并歸排序的通用公式如下,

其他都比較容易理解,為什么way數(shù)是B-1?

因?yàn)閙emory一共B個(gè)buffer,需要留一個(gè)output,剩下的用于merge,所以最多是B-1路并歸排序

?

如果我們有B+ index的情況下,

分兩種情況,要排序的字段有Clustered B+索引,那么直接從左到右遍歷葉子節(jié)點(diǎn)就好

排序的字段不是Clustered B+索引,比如是secondary 索引

那么從索引里面只能獲取到排好序的id,然后要通過id去Clustered B+索引中取真正的value,效率也很低,每個(gè)record都需要一次io

?

Aggregation

Aggregation有兩種思路,

一種先排序sorting,然后再按順序做aggregate

這個(gè)方法明顯的問題,就是比較費(fèi),有些場(chǎng)景不需要sort,比如group by,distinct

所以第二種思路是Hashing,

在memory里面臨時(shí)維護(hù)一個(gè)hash table,去重或聚合都在hash table上完成

問題就是,如果hash table太大,內(nèi)存放不下怎么辦?

所以解法的思路,放不下,就切開,切成能放下的一個(gè)個(gè)partition,并且要保證一個(gè)key的數(shù)據(jù)都在一個(gè)partition里面,這樣只要保證內(nèi)存能夠放下一個(gè)partition就可以aggregate,不需要去讀其他的partition

第一次partition劃分成幾個(gè)partition,如果內(nèi)存B個(gè)buffer,劃分成B-1個(gè)partition;如果劃分完了某個(gè)partition還是放不下怎么辦,那就繼續(xù)劃分,直到所有partition都可以放到內(nèi)存中

這里有幾個(gè)問題,

首先,一個(gè)partition應(yīng)該不止一個(gè)key,如果只有一個(gè),第二步里面的h2感覺沒用
第二,假設(shè)數(shù)據(jù)是均勻分布的,不會(huì)出現(xiàn)太大的傾斜,不會(huì)有partition overflow

?

Join

為什么需要join?

因?yàn)椴煌臄?shù)據(jù)存在不同的表里面,所以要查詢就需要關(guān)聯(lián)
那么為什么不能放在一張表里面,關(guān)系表的設(shè)計(jì)有范式的要求,避免大量的數(shù)據(jù)重復(fù)

?

Join Operator Output

直接輸出data,這樣好處是,后續(xù)operator不用回到數(shù)據(jù)表再去讀數(shù)據(jù)
這個(gè)方法比較實(shí)用于TP需求,結(jié)果數(shù)據(jù)較少的情況

僅僅輸出ids,適合AP需求,join結(jié)果集非常大的情況

尤其適用于列存,因?yàn)檫@樣你只需要讀出join id列,也不浪費(fèi)

然后在最后要顯示的時(shí)候,才去把需要的數(shù)據(jù)從表里面查出來,這叫做late materialization

這樣的好處,過程中可能還有其他的join,過濾等,所以開始讀可能浪費(fèi),到最后真正需要的時(shí)候再讀

?

Join Cost

如何去評(píng)價(jià)join算法的好壞,就是要評(píng)價(jià)cost

傳統(tǒng)的數(shù)據(jù)庫的瓶頸在disk IO,所以這里就以磁盤IO的次數(shù)來評(píng)價(jià)join算法的好壞,這個(gè)和為何使用B+tree作為index的理由一樣
所以就是讀寫page的個(gè)數(shù)

?

Join算法?

Nested Loop Join

Simple,直覺的方式就是遍歷兩個(gè)表
這里的概念,分為Outer和Inner表
從Cost上看,最要取決于Outer的tuples數(shù),所以如果把較小的表N作為Outer會(huì)效率高些  

比較明顯的問題是,沒有必要讀那么多遍的inner表

如果我能把outer表直接放在內(nèi)存中,那么只需要讀一遍inner就可以了,如果不行就用如下的block的方式

如果內(nèi)存大小是B,那么要用兩塊來放inner和output,所以可以用B-2來放outer

Cost,outer表M需要讀一次,inner表需要讀M/(B-2)次

這里也寫了,如果memory比較大,那么cost就是M+N,只需要讀一遍inner

?

如果有index,是否可以加快join的效率?應(yīng)該可以,但是效果要看是什么index,如果hash,C=O(1),B+tree,C=O(logn)

?

Sort-Merge Join?

這個(gè)方法要求,兩個(gè)表先排序,然后做一輪幷歸就可以完成join
所以這個(gè)方法適用于,兩個(gè)表本身就有序,或是在join key上有index
這個(gè)方法附帶的好處是結(jié)果有序

這個(gè)算法的Cost,主要是兩個(gè)表排序的cost,幷歸的cost就是M+N

?

Hash Join

HashJoin分為兩步,兩步的hash函數(shù)用同一個(gè)

Build,對(duì)較小的表建臨時(shí)的hash table

Probe,讀取另一張表,進(jìn)行join

這有個(gè)類似的問題,Hash Table里面存什么?

當(dāng)然可以直接存join的結(jié)果,也可以存tuple id,這個(gè)選擇就取決于場(chǎng)景

?

自然有個(gè)疑問,如果內(nèi)存放不下這個(gè)hash table怎么辦?

既然放不下,就需要分而治之,兩個(gè)表用相同的hash函數(shù),hash到相同數(shù)目的buckets里面去

在內(nèi)存中,一次只讀一組bucket來進(jìn)行join,是不是很ok

?

?那么如果hash成bucket的時(shí)候,不均衡,一個(gè)bucket也overflow,怎么辦?答案是繼續(xù)分

?

Grace Hash Join的cost

?

?所有join算法的Cost對(duì)比,

?

?

轉(zhuǎn)載于:https://www.cnblogs.com/fxjwind/p/10906161.html

總結(jié)

以上是生活随笔為你收集整理的CMU Database Systems - Sorting,Aggregation,Join的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。