與 insert 不同,delete 有 where 子句,因此能運用第 2 章「WHERE 子句」介紹的所有方法直接從索引獲益。
實際上
delete的運作就像一段select,後面再多一個「刪除找到的列」的步驟。
而刪除一列的實際過程與插入新列相似——尤其是移除索引中的參照與維持索引樹平衡這些動作。因此效能曲線與 insert 非常相近。

圖 8.2:依索引數量的 delete 效能
為什麼圖中沒有「零索引」那一格#
理論上我們會預期「沒有任何索引」時 delete 效能最好(如同 insert)。但若沒有索引,資料庫必須讀完整張表才能找到要刪的列——刪除本身很快,尋找卻極慢。因此這種情況並未列入圖中。
儘管如此,在沒有索引的情況下執行 delete 有時仍然合理,就像「查詢會回傳資料表一大部分時,不用索引的 select 也合理」一樣。
TRUNCATE TABLE#
沒有 where 子句的 delete 是資料庫顯然用不上索引的例子。這種特例有自己的 SQL 指令:truncate table。
它的效果與「不帶 where 的 delete」相同,但一次刪光所有列,速度極快。不過有兩個重要副作用:
- 它會隱式 commit(PostgreSQL 例外)。
- 它不會執行任何觸發器(trigger)。
延伸:MVCC 的副作用
多版本並行控制(MVCC, multiversion concurrency control)是讓並行資料存取不互相阻塞、並提供一致交易視圖的資料庫機制。但各家實作差異甚大,甚至可能對效能造成可觀影響。
以 PostgreSQL 為例:它只在資料表層級保存版本(可見性)資訊——刪除一列時,只是在資料表區塊中設定「已刪除」旗標。因此 PostgreSQL 的 delete 效能不取決於表上的索引數量;資料表列的實體刪除與相關的索引維護,要到 VACUUM 程序執行時才進行。