無索引 = 全表掃描。大表小結果集查詢無索引會導致災難性效能。但低基數欄位(如性別)建索引反而有害(過度索引)。
-- 查詢:WHERE area='bj' AND age=22
-- 單列索引:只能用一個
-- 複合索引:(area, age) 效能指數級提升
-- (area, age, salary) 等價於 (area,age,salary) + (area,age) + (area)
最常用過濾欄位放最左,依基數遞減排序。
單列含 NULL 不入索引;複合索引任一欄位 NULL 導致該行不入複合索引。設計時 禁止預設 NULL,用 NOT NULL DEFAULT '' 或 0。
CHAR(255) 欄位若前 10-20 字元區分度高,建 INDEX(name(10))。節省空間、減少 I/O、提升快取命中率。
WHERE 用了索引,ORDER BY 不會再用索引(where_col, order_col)ORDER BYLIKE 'prefix%' → 走索引LIKE '%suffix' / LIKE '%mid%' → 全表掃描FULLTEXT INDEX + MATCH() AGAINST()-- 錯誤:YEAR(adddate) = 2023 → 索引失效
-- 正確:adddate >= '2023-01-01' AND adddate < '2024-01-01'
任何 col + 1、UPPER(col)、DATE_FORMAT(col) 都會導致索引失效。
NOT IN → NOT EXISTS (SELECT 1 FROM ...) 或 LEFT JOIN ... WHERE b.id IS NULLid != 3 → id < 3 OR id > 3(仍可能全掃,視基數決定)OR 跨欄位通常全掃,改用 UNION ALL 分開查詢再合併WHERE/JOIN 欄位有索引NULL 預設值汙染索引LIKE 僅用前綴匹配NOT IN/OR 反模式ANALYZE TABLE 更新統計資訊