資料庫索引是什麼?為什麼能讓查詢變快
在資料量變大之後,資料庫效能的關鍵往往不在硬體,而在「查詢怎麼做」。索引(Index)就是資料庫用來加速查詢的核心機制。如果沒有索引,資料庫幾乎只能一筆一筆掃描資料;有了索引,查詢速度可以從「秒級」直接降到「毫秒級」。
一、什麼是資料庫索引
資料庫索引是一種額外建立的資料結構,用來快速定位資料在資料表中的位置。 它的本質不是資料本身,而是「資料的對照表」。
可以把索引想成書本最後的目錄:
-
書的內容 = 資料表(Table)
-
章節與頁碼 = 索引
-
查頁碼 = 查詢資料
如果沒有目錄,你只能從第一頁一路翻到最後一頁;有目錄,你可以直接跳到指定頁數。
二、沒有索引時,資料庫怎麼查資料
假設有一個使用者資料表 users:
SELECT * FROM users WHERE email = 'test@example.com';
沒有索引的情況
資料庫只能執行 全表掃描(Full Table Scan):
-
從第一筆資料開始
-
一筆一筆比對
email -
直到找到符合條件的資料或掃完整張表
時間複雜度接近 O(n),資料越多,查詢越慢。
三、有索引之後,查詢為什麼會變快
1. 索引本身是有結構的
多數關聯式資料庫(MySQL、PostgreSQL)使用的索引結構是 B-Tree 或 B+Tree。
B-Tree 的特性:
-
資料是排序過的
-
查詢時可以「一層一層縮小範圍」
-
時間複雜度接近 O(log n)
這讓資料庫能快速定位資料位置,而不是全部掃過。
2. 索引的實際查詢流程
建立索引後:
CREATE INDEX idx_users_email ON users(email);
查詢流程會變成:
-
到索引樹中查找
test@example.com -
直接取得該值對應的資料位置(Row ID)
-
依位置讀取資料
資料量越大,差距越明顯。
四、索引到底存了什麼
一個索引通常包含:
-
索引欄位的值(如 email)
-
對應資料列的位置(主鍵或指標)
索引不一定包含整筆資料,而是「怎麼快速找到那筆資料」。
五、常見索引類型
1. 主鍵索引(Primary Key Index)
-
自動建立
-
唯一且不可為 NULL
-
查詢效率最高
PRIMARY KEY (id)
2. 唯一索引(Unique Index)
-
確保欄位值不重複
-
同時具備查詢加速功能
CREATE UNIQUE INDEX idx_users_email ON users(email);
3. 一般索引(Non-Unique Index)
-
最常見
-
可重複值
-
用於加速查詢
CREATE INDEX idx_users_name ON users(name);
4. 複合索引(Composite Index)
-
多個欄位組成
-
依「欄位順序」生效
CREATE INDEX idx_users_city_age ON users(city, age);
查詢生效:
WHERE city = 'Taipei' WHERE city = 'Taipei' AND age = 18
不生效:
WHERE age = 18
六、索引為什麼不是越多越好
索引不是免費的。
1. 影響寫入效能
每次 INSERT、UPDATE、DELETE:
-
資料表要更新
-
所有相關索引也要更新
索引越多,寫入成本越高。
2. 佔用額外空間
索引本身是獨立的資料結構,會吃磁碟與記憶體。
3. 錯誤索引反而沒用
以下情況索引可能無法使用:
- 對索引欄位使用函式
WHERE DATE(created_at) = '2025-01-01'
- 使用前置萬用字元
WHERE name LIKE '%abc'
- 資料選擇性太低(例如性別)
七、什麼欄位適合建立索引
適合:
-
常用於
WHERE條件 -
常用於
JOIN -
常用於
ORDER BY -
高選擇性(值分布廣)
不適合:
-
經常變動的欄位
-
值種類很少的欄位
-
很少被查詢的欄位
八、索引與查詢優化的關係
索引只是查詢優化的一部分。
良好的查詢效能還需要:
-
合理的 SQL 寫法
-
避免不必要的
SELECT * -
善用
EXPLAIN查看查詢計畫 -
正確設計資料表結構
索引是工具,不是萬靈丹。
九、總結
資料庫索引的本質,是用空間換時間。
-
沒索引 → 全表掃描 → 線性時間
-
有索引 → 樹狀結構 → 對數時間
-
索引用得好 → 查詢快數十倍
-
索引用錯 → 寫入變慢、空間浪費
理解索引的運作原理,才能在資料量成長時,讓系統依然保持穩定與高效。