叢集索引一張表只有一個,非叢集索引是另一份帶 pointer 的結構

叢集索引(clustered)非叢集索引(non-clustered)
數量每張表只有一個(unique index)可以有多個
通常是誰該表的 primary key其他欄位或多欄位組合
內容—索引的組成欄位 + 一個指向原始資料的 pointer

非叢集索引本身就是「多個欄位組合成的一份資料結構」,它不存整列資料,只存索引欄位和一個「回去拿資料」的憑據——所以用它查完之後,還要再走一趟把原始資料撈回來,也就是 全表掃描和索引掃描的適用場景是相反的 裡索引掃描的第二步。

「pointer」這個說法要分資料庫

上表說的 pointer 對 PostgreSQL 成立,對 MySQL 不成立:

  • PostgreSQL:索引存的是 CTID(物理位置),確實是指標,二級索引直接指向 Heap
  • MySQL (InnoDB):二級索引存的是主鍵值,不是位址——所以要先回主鍵索引再走一次,這叫回表

兩邊的差別與後果見 加上二級索引之後,主鍵查詢的快慢反過來;為什麼 InnoDB 能這樣放見 MySQL 把資料放在主鍵索引的葉子,PostgreSQL 放在獨立的 Heap。

索引為什麼用 B+ tree 見 B-tree 靠一個節點放多個鍵把樹壓矮,換到更少的讀取次數。