前言

剛開始接觸資料庫效能問題時,常常會聽到一句話:

「這個查詢很慢,可能要加 index。」

但 index 到底是什麼?為什麼加了它查詢就可能變快?

這篇先不鑽太深的資料結構,而是用比較直覺的方式整理 index 的基本概念。

Index 可以想成書的目錄

假設你手上有一本很厚的書,想找「例外處理」這個主題。

如果沒有目錄,你只能從第一頁開始慢慢翻。

但如果有目錄,你可以先查目錄,找到相關章節在哪一頁,再直接翻過去。

資料庫的 index 概念也很像。

沒有 index 時,資料庫可能需要掃描整張表,逐筆檢查資料是否符合條件。

有 index 時,資料庫可以透過索引結構更快找到符合條件的資料。

最常見的使用情境

假設有一張 Users 表:

1
2
3
4
5
6
CREATE TABLE Users (
Id INT PRIMARY KEY,
Email VARCHAR(255),
Name VARCHAR(100),
CreatedAt DATETIME
);

如果系統常常用 Email 查使用者:

1
2
3
SELECT *
FROM Users
WHERE Email = 'hikari@example.com';

Email 就可能是適合建立 index 的欄位。

1
2
CREATE INDEX IX_Users_Email
ON Users (Email);

這樣資料庫就不用每次都從頭掃到尾,而是可以利用 index 更快定位資料。

不是每個欄位都要加 Index

index 不是越多越好。

因為 index 本身也需要儲存空間,而且資料新增、修改、刪除時,資料庫也要同步維護 index。

也就是說,index 可以加快某些查詢,但也可能讓寫入成本增加。

比較適合考慮加 index 的欄位通常有:

  • 常出現在 WHERE 條件中的欄位。
  • 常用來 JOIN 的欄位。
  • 常用來排序的欄位。
  • 資料量大,且查詢頻率高的欄位。

比較不適合盲目加 index 的情況:

  • 資料量很小。
  • 欄位幾乎不拿來查詢。
  • 欄位值重複性太高,例如只有 true / false
  • 寫入頻率非常高,但查詢不依賴該欄位。

Index 也要配合查詢方式

不是建立了 index,查詢就一定會使用它。

例如你在 Email 上建立 index,但查詢時對欄位做函式處理:

1
2
3
SELECT *
FROM Users
WHERE LOWER(Email) = 'hikari@example.com';

在某些資料庫或情境下,這可能會讓 index 不容易被有效使用。

另外,像是模糊查詢也要注意:

1
2
3
SELECT *
FROM Users
WHERE Email LIKE '%example.com';

前面有 % 的查詢通常不利於一般 index 發揮效果。

所以 index 不是單獨看欄位,而是要搭配實際查詢方式一起判斷。

可以用執行計畫確認

判斷 index 有沒有幫助,不應該只靠感覺。

大多數資料庫都提供查看執行計畫的方式,可以看到查詢是掃整張表,還是有使用 index。

例如在 SQL Server 可以看 Execution Plan,在 MySQL 可以用 EXPLAIN

透過執行計畫,我們可以更清楚知道資料庫實際怎麼查資料。

結語

index 可以幫助查詢變快,但它不是萬靈丹。

我會用這幾個問題先判斷:

  • 這個欄位常被查詢嗎?
  • 資料量是否已經大到需要優化?
  • 查詢方式是否能有效使用 index?
  • 加了 index 之後,寫入成本是否可以接受?

先理解這些基本概念,再去看執行計畫和實際查詢時間,會比盲目加 index 安全很多。