MySQL 把資料放在主鍵索引的葉子,PostgreSQL 放在獨立的 Heap

這兩套資料庫最本質的差別不在語法、不在功能,而在資料行實際躺在哪裡。 MySQL(InnoDB)是索引組織表(Index-Organized Table),PostgreSQL 是堆疊表(Heap Table)。 後面所有的差異——讀取路徑、寫入放大、空間膨脹——都是從這一條長出來的。

兩種放法

MySQL (InnoDB)PostgreSQL
資料行放在主鍵 B+ Tree 的葉子節點裡(表就是索引)獨立的 Heap,像一堆文件丟進大桶子,沒有順序
物理排列按主鍵順序排列無序
索引存的是主鍵索引的葉子=資料本身一律是指針(CTID),指向 Heap 中的物理位置
主鍵與二級索引主鍵是本體,其他是附屬平權,沒有主從之分

主鍵查詢:差一趟

MySQL   找到主鍵索引的葉子 → 資料就在這        ← 1 趟
PG      找到索引葉子 → 拿到 CTID → 去 Heap 撈  ← 2 趟(多一次 I/O)

所以用主鍵查時 MySQL 快——找到索引就等於找到資料,不需要二次跳轉。

各自的代價

  • MySQL:主鍵很長或很亂(例如 UUID)會讓整個表結構碎片化,寫入效能大幅下降——因為資料是照主鍵物理排序的,亂序主鍵等於每次都插在中間
  • PostgreSQL:寫入很快(直接丟進 Heap),但連主鍵查詢都要多跳一次

這條差異的下游