外文翻譯丨“王者對戰”之 MySQL 8 vs PostgreSQL 10(深度)

外文翻譯丨“王者對戰”之 MySQL 8 vs PostgreSQL 10(深度)

參與翻譯 (5人) : 雪落無痕xdj, 無若, LinuxTech, Tocy, kevinlinkai

英文原文:Showdown: MySQL 8 vs PostgreSQL 10

既然 MySQL 8 和 PostgreSQL 10 已經發布了,現在是時候回顧一下這兩大開源關係型數據庫是如何彼此競爭的。

在這些版本之前,人們普遍認為,Postgres 在功能集表現更出色,也因其“學院派”風格而備受稱讚,MySQL 則更善長大規模併發讀/寫。

但是隨著它們最新版本的發佈,兩者之間的差距明顯變小了。

1、特性比較

讓我們來看看我們都喜歡談論的“時髦”功能。

外文翻譯丨“王者對戰”之 MySQL 8 vs PostgreSQL 10(深度)

過去經常會說 MySQL 最適合在線事務,PostgreSQL 最適合分析流程。但現在不是了。

公共表表達式(CTEs) 和窗口函數是選擇 PostgreSQL 的主要原因。但是現在,通過引用同一個表中的 boss_id 來遞歸地遍歷一張僱員表,或者在一個排序的結果中找到一箇中值(或 50%),這在 MySQL 上不再是問題。

在 PostgreSQL 中進行復制缺乏配置靈活性,這就是 Uber 轉向 MySQL 的原因。但是現在,有了邏輯複製特性,就可以通過創建一個新版本的 Postgres 並切換到它來實現零停機升級。在一個巨大的時間序列事件表中截斷一個陳舊的分區也要容易得多。

就特性而言,這兩個數據庫現在都是一致的。

2、有哪些不同之處呢?

現在,我們只剩下一個問題 —— 那麼,選擇一個而不選另一個的原因是什麼呢?

生態系統是其中一個因素。MySQL 有一個充滿活力的生態系統,包括 MariaDB、Percona、Galera 等等,以及除 InnoDB 以外的存儲引擎,但這也可能是和令人困惑的。Postgres 的高端選擇有限,但隨著最新版本引入的新功能,這會有所改變。

治理是另一個因素。當 Oracle(或最初的 SUN)收購 MySQL時,每個人都擔心他們會毀掉這個產品,但在過去的十年裡,這並不是事實。事實上,在收購之後,發展反倒加速了。而 Postgres 在工作管理和協作社區方面有著豐富的經驗。

基礎架構不會經常改變,雖然近來沒有對這方面的詳細討論,這也是值得再次考慮的。

來複習下:

外文翻譯丨“王者對戰”之 MySQL 8 vs PostgreSQL 10(深度)

3、進程vs線程

當 Postgres 派生出一個子進程來建立連接時,每個連接最多可以佔用 10MB。與 MySQL 的線程連接模型相比,它的內存壓力更大,在 64 位平臺上,線程的默認堆棧大小為 256KB。(當然,線程本地排序緩衝區等使這種開銷變得不那麼重要,即使在不可以忽略的情況下,仍然如此。)

儘管“寫時複製”保存了一些與父進程共享的、不可變的內存狀態,但是當您有 1000 多個併發連接時,基於流程的架構的基本開銷是很繁重的,而且它可能是容量規劃的最重要的因素之一。

也就是說,如果你在 30 臺服務器上運行一個 Rails 應用,每個服務器都有 16 個 CPU 核心 32 線程,那麼你有 960 個連接。可能只有不到 0.1% 的應用會超出這個範圍,但這是需要記住的。

4、聚簇索引 vs 堆表

聚簇索引是一種表結構,其中的行直接嵌入其主鍵的 b 樹結構中。一個(非聚集)堆是一個常規的表結構,它與索引分別填充數據行。

有了聚簇索引,當您通過主鍵查找記錄時,單次 I/O 就可以檢索到整行,而非集群則總是需要查找引用,至少需要兩次 I/O。由於外鍵引用和 JOIN 將觸發主鍵查找,所以影響可能非常大,這將導致大量查詢。

聚簇索引的一個理論上的缺點是,當您使用二級索引進行查詢時,它需要遍歷兩倍的樹節點,第一次掃描二級索引,然後遍歷聚集索引,這也是一棵樹。

但是,如果按照現代表設計的約定,將一個自動增量整數作為主鍵[1]——它被稱為代理鍵——那麼擁有一個聚集索引幾乎總是可取的。更重要的是,如果您做了大量的 ORDER BY id 來檢索最近的(或最老的)N 個記錄的操作,我認為這是很適用的。

Postgres 不支持聚集索引,而 MySQL(InnoDB)不支持堆。但不管怎樣,如果你有大量的內存,差別應該是很小的。

5、頁結構和壓縮

Postgres 和 MySQL 都有基於頁面的物理存儲。(8KB vs 16KB)

外文翻譯丨“王者對戰”之 MySQL 8 vs PostgreSQL 10(深度)

PostgreSQL 物理存儲的介紹

頁結構看起來就像右邊的圖。它包含一些我們不打算在這裡討論的條目,但是它們包含關於頁的元數據。條目後面的項是一個數組標識符,由指向元組或數據行的(偏移、長度)對組成。在 Postgres 中,相同記錄的多個版本可以以這種方式存儲在同一頁面中。

外文翻譯丨“王者對戰”之 MySQL 8 vs PostgreSQL 10(深度)

MySQL 的表空間結構與 Oracle 相似,它有多個層次,包括層、區段、頁面和行層。

此外,它還有一個用於撤銷的單獨段,稱為“回滾段”。與 Postgres 不同的是,MySQL 將在一個單獨的區域中保存同一記錄的多個版本。

如果存在一行必須適合兩個數據庫的單個頁面,,這意味著一行必須小於 8KB。(至少有 2 行必須適合 MySQL 的頁面,恰巧是 16KB/2 = 8KB)

外文翻譯丨“王者對戰”之 MySQL 8 vs PostgreSQL 10(深度)

那麼當你在一個列中有一個大型 JSON 對象時會發生什麼呢?

Postgres 使用 TOAST,這是一個專用的影子表(shadow table)存儲。當行和列被選中時,大型對象就會被拉出。換句話說,大量的黑盒不會汙染你寶貴的緩存。它還支持對 TOAST 對象的壓縮。

MySQL 有一個更復雜的特性,叫做透明頁壓縮,這要歸功於高端 SSD 存儲供應商 Fusio-io 的貢獻。它設計目的是為了更好地使用 SSD,在 SSD 中,寫入量與設備的壽命直接相關。

對 MySQL 的壓縮不僅適用於頁面外的大型對象,而且適用於所有頁面。它通過在稀疏文件中使用打孔來實現這一點,這是被 ext4 或 btrfs 等現代文件系統支持的。

有關更多細節,請參見:在 FusionIO 上使用新 MariaDB 頁壓縮獲得顯著的性能提升。

6、更新的開銷

另一個經常被忽略的特性,但是對性能有很大的影響,並且可能是最具爭議的話題,是更新。

這也是Uber放棄Postgres的另一個原因,這激起了許多Postgres的支持者來反駁它。

  • MySQL 對Uber可能是合適的, 但是未必對你合適
  • 一篇PostgreSQL對Uber的回應 (PDF)

兩者都是MVCC數據庫,它們可以隔離多個版本的數據。

為了做到這一點,Postgres將舊數據保存在堆中,直到被清空,而MySQL將舊數據移動到一個名為回滾段的單獨區域。

在Postgres中,當您嘗試更新時,整個行必須被複制,以及指向它的索引條目也被複制。這在一定程度上是因為Postgres不支持聚集索引,所以從索引中引用的一行的物理位置不是由邏輯鍵抽象出來的。

為了解決這個問題,Postgres使用了堆上元組(HOT),在可能的情況下不更新索引。但是,如果更新足夠頻繁(或者如果一個元組比較大),元組的歷史可以很容易地超過8 KB的頁面大小,跨越多個頁面並限制該特性的有效性。修剪和/或碎片整理的時間取決於啟發式解決方案。另外,設置不超過100的填充參數會降低空間效率——這是一種很難在創建表時考慮的折衷方案。

這種限制更深入; 因為索引元組沒有關於事務的任何信息,所以直到9.2之前一直不能支持僅索引掃描。 它是所有主要數據庫(包括MySQL,Oracle,IBM DB2和Microsoft SQL Server)支持的最古老,最重要的優化方法之一。 但即使使用最新版本,當有許多UPDATE在可見性映射中設置髒位時,Postgres也不能完全支持僅索引掃描,並且在我們不需要時經常選擇Seq掃描。

在MySQL上,更新發生在原地,舊的行數據被封存在一個稱為回滾段的獨立區域中。 結果是你不需要VACUUM,並且提交非常快,而回滾相對較慢,這對於大多數用例來說是一個可取的折衷。

它也足夠聰明,儘快清除歷史。 如果事務的隔離級別設置為READ-COMMITTED或更低,則在語句完成時清除歷史記錄。

事務記錄的大小不會影響主頁面。 碎片化是一個偽命題。 因此,在MySQL上能更好,更可預測整體性能。

7、Garbage Collection 垃圾回收

在Postgres中VACUUM上開銷很高,因為它在主要工作在堆區,造成了直接的資源競爭。它感覺就像是編程語言中的垃圾回收 - 它會擋在路上,並隨時讓你停下來。

為具有數十億記錄的表配置autovacuum仍然是一項挑戰。

在MySQL上清除(Purge)也可能相當繁重,但由於它是在單獨的回滾段中使用專用線程運行的,因此它不會以任何方式影響讀取的併發性。即使使用默認配置,變膨脹的回滾段使你執行速度減慢的可能性也是很低的。

擁有數十億記錄的繁忙表不會導致MySQL上的歷史數據膨脹,諸如存儲上的文件大小和查詢性能等事情上幾乎是可以預測的並且很穩定。

開源中國翻譯頻道:對於技術達人來說,廣納知識點是進步的源泉。通過閱讀技術文章我們可以學到很多東西,既可以學到業務技能,又可以瞭解行業動態,最不濟,也鍛鍊了閱讀和學習的能力。開源中國翻譯頻道旨在每天為用戶推薦並翻譯優質的外網文章。再也不用怕因為英語不過關,被擋在許多技術文章的門外。


分享到:


相關文章: