tft每日頭條

 > 生活

 > sqlserverpostgresql性能對比

sqlserverpostgresql性能對比

生活 更新时间:2025-02-11 18:24:02

本文來源于數據庫架構之美,作者數據庫架構之美

我們知道mysql沒有hash join,也沒有merge join,所以在連接的時候隻有一種算法nest loop join,nl join使用驅動表的結果集作為外表到内表中查找每一條記錄,如果有索引,就會走索引掃描,沒有索引就會全表掃。

nl join并不能适用所有場景,例如兩個表都是很大的表的等值連接,這種場景是hash join所擅長的,而且是生産環境中最常見的場景。mysql在這個時候就顯得力不從心,所以在使用mysql時我們可能會制定如下規範:禁止使用大表連接。這也是mysql永遠的痛。不過據說8.0版本已經将hash join作為一個需求納入了,我們拭目以待吧。

相比起來,postgresql的優化器十分的強勁。支持了hash join、nest loop、sort merge join,掃描算法支持seq scan、index scan、index only scan,同時還支持堆内元組技術(HOT)。在postgresql11版本中還加入了并行掃描,親測在兩張大表(一張1.6億一張256萬數據,均無索引)做join結果集300多萬,pg開啟并行大概20s以内就跑出結果,強于其他數據庫。

上面讨論了兩表join的算法,下面看看多表join時mysql和pg是如何處理的。多表join其實涉及到一個問題:如何找到代價最小的最優路徑。為什麼會有這個問題呢?因為在多表連接時,每兩個表之間連接具有一個代價值,優化器會根據代價估算調整不同表join的順序,最後算出一個最優或者近似最優代價,使用這個代價生成執行計劃,這樣就涉及到圖論中的最短路徑問題,不同的連接順序組合代表了圖的遍曆,最優代價其實就是求無源圖的最短路徑問題。我們知道兩種主流的最短路徑算法是迪傑斯特拉(Dijkstra)算法和弗洛伊德(floyd)算法,這兩種算法也是動态規劃中的經典算法。

貪心算法的前提是确定源點,算法思想也和名字很像,隻找當前步驟的最優解,是一種深度優先的解法,算法複雜度是O(n²)找到後繼續深入下一層,直至達到終點。比如上圖從A到G,使用貪心算法的路徑是A->B->D->G算法,代價是1 2 6=9,很明顯這并不是最優解,最優解我們肉眼可以看出來是A->C->F->G,代價是2 3 1=6。所以我們看貪心算法并不是全局最優的,但是優點是算法複雜度低,mysql可能也是基于這種考慮而使用貪心算法,不想将時間都浪費在計算代價上了,因為如果關聯的表特别多,那麼代價的計算是指數級增長,所以貪心算法雖然不是最優解,但是在連接表的數量很大的情況下具有一定優勢。

Postgresql:

再來看看pg使用的動态規劃,動态規劃解決的是無源最短路徑問題,我們想象一下其實多表連接本身就是一個無源最短路徑問題,隻是mysql在進行連接的時候随機選了一個作為起點而已。

動态規劃的思想是将問題分解為子問題,将問題遞推為子問題進行解決。以floyd算法為例。算法使用鄰接矩陣來表示每個點之間的距離,如果沒有連線,則代表無窮大。比如下面這個圖:

sqlserverpostgresql性能對比(MySQL和PostgreSQL在多表連接算法上的差異)1

弗洛伊德算法使用矩陣記錄節點直接距離,它的強大之處在于它經過若幹次計算後得到任意兩個節點直接的最短距離,是真正意義上的無源最短路徑算法,但是它的算法複雜度也比較高,是O(n³)。下面介紹一下該算法,算法的核心思想是如果a[ij]>a[ik] a[kj],那麼a[ij]=a[ik] a[kj],對于每兩個節點ab之間的距離,如果存在第三個中間節點c使得acb的距離更短,那麼ab的距離使用acb代替,并更新到矩陣。這樣的遍曆過程我們大緻就理解了需要三層循環,裡面的兩層循環是對于ab、ac、ad...de總共(n-1)*(n-1)種選擇(自己對自己的距離不用計算)計算每個中間節點(最外層循環)的距離是否更小。矩陣計算過程如下:

sqlserverpostgresql性能對比(MySQL和PostgreSQL在多表連接算法上的差異)2

對于第一行,依次計算ab,ac,ad,ae的距離是否有第三個節點進行替換,對于ab計算發現,ab<ac cb&&ab<ad db&&ab<ae eb,所以ab不用更新,同理ac也不用更新,對于ad,計算得到ab bd=6,ac cd=∞,ae ed=∞,于是更新ad=6,同理計算更新ae=8;然後依次計算下面幾行。全部遍曆完,經曆了三層循環,算法複雜度是O(n³)。pg使用該算法能夠得到最優執行計劃,但是在表的個數很多時計算代價所付出的代價也很大。

綜上,mysql使用貪心算法隻能得到局部最優執行計劃,但是計算最優解所消耗的代價較小,而pg使用動态規劃能夠得到最優執行計劃,但是計算最優解算法複雜度較高,代價較大。但是總體上mysql的優化器相比pg還是有很大差距,pg的優化器甚至引入了基因算法,有很多比較學術的考量,當得起學術派數據庫的稱号,也希望mysql能夠越來越好吧。

活動預告


2019 數據技術嘉年華來啦!現場大咖雲集,與你共暢數據的魅力。現在加入,盡享早鳥票價優惠:

sqlserverpostgresql性能對比(MySQL和PostgreSQL在多表連接算法上的差異)3

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved