首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 索引深度解析:加速動態網站的核心優化策略

     編輯:MySQL 資料庫相關知識

索引:數據庫性能的「導航儀」

在關係型數據庫中,索引是提升查詢速度的最關鍵結構。MySQL 所有索引均以 B+ 樹 形式存儲。若無索引,執行查詢時 MySQL 必須掃描整張表(全表掃描),數據量越大代價越高;有了索引,MySQL 可直接定位到目標行,對於百萬級數據,速度提升可達百倍以上。

索引類型全景圖

類型特點創建語法示例適用場景
普通索引 最基本,無唯一性約束 CREATE INDEX idx_name ON tbl(col);
ALTER TABLE tbl ADD INDEX idx_name (col);
頻繁出現在 WHERE、JOIN、ORDER BY 中的非唯一列
唯一索引 索引列值不可重複,允許 NULL CREATE UNIQUE INDEX uk_email ON users(email); 業務鍵(如郵箱、身份證號)
主鍵 特殊唯一索引,不允許 NULL,每表僅一個 CREATE TABLE t (id INT PRIMARY KEY, ...);
ALTER TABLE t ADD PRIMARY KEY (id);
表的唯一標識,通常為自增 ID
全文索引 MySQL 3.23.23+ 支持,針對 VARCHAR/TEXT ALTER TABLE articles ADD FULLTEXT(content); 大文本字段的關鍵詞搜索(中文需分詞器)
空間索引 MySQL 4.1+ 支持,針對幾何類型 ALTER TABLE geom ADD SPATIAL INDEX(loc); GIS 應用,經緯度範圍查詢

單列 vs 多列索引:最左前綴原則

假設表 people 有索引 INDEX idx_name_age (lastname, firstname, age):

  • 生效:WHERE lastname='Smith'、WHERE lastname='Smith' AND firstname='John'、WHERE lastname='Smith' AND firstname='John' AND age>30
  • 失效:WHERE firstname='John'(非最左列)、WHERE age>30(跳過前綴)

經驗法則:將選擇性最高(唯一值最多)的列放在最左;避免過多列組合(建議 ≤3 列),否則索引膨脹、維護成本高。

索引優化實戰清單

  1. EXPLAIN 是金標準:EXPLAIN SELECT ... 觀察 type(應為 ref/range/eq_ref,避免 ALL)、key(實際用到的索引)、rows(預估掃描行數)。
  2. 覆蓋索引:查詢列全在索引中,Extra 顯示 Using index,避免回表,極大提速。
  3. 避免索引失效陷阱:
    • 列上使用函數/運算:WHERE YEAR(create_time)=2023 → 改為 WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01'
    • 隱式類型轉換:WHERE phone=13800138000(phone 為 VARCHAR) → 加引號
    • LIKE '%keyword%' 導掃描 → 僅 LIKE 'keyword%' 走索引
    • OR 連接非索引列 → 改用 UNION 或建立聯合索引
  4. 主鍵設計:優先使用無業務含義的自增整型(INT/BIGINT),保持 B+ 樹順序寫入,減少頁分裂;避免 UUID、長字符串作主鍵。
  5. 定期維護:ANALYZE TABLE 更新統計信息;OPTIMIZE TABLE 整理碎片(InnoDB 可用 ALTER TABLE ... ENGINE=InnoDB 重建)。

經典案例:多表關聯優化

-- 原始慢查詢(三張表無有效索引)
SELECT t1.id, t2.name, t3.amount
FROM orders t1
JOIN customers t2 ON t1.cust_id = t2.id
JOIN payments t3 ON t1.id = t3.order_id
WHERE t1.status = 'paid' AND t2.city = 'Beijing';

-- 優化步驟
ALTER TABLE orders ADD INDEX idx_status_cust (status, cust_id);
ALTER TABLE customers ADD INDEX idx_city_id (city, id);
ALTER TABLE payments ADD INDEX idx_order_id (order_id);

-- EXPLAIN 驗證:type 變為 ref,rows 大幅下降

總結

索引是雙刃劍:讀快寫慢、佔用空間。核心原則是「為查詢建索引,而非為表建索引」。持續監控慢查詢日誌(slow_query_log)、定期 EXPLAIN、遵循最左前綴、善用覆蓋索引,是將 MySQL 性能榨乾的必經之路。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved