首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 連接查詢中索引的關鍵作用:從 75 秒優化到 0.07 秒的實戰分析

     編輯:MySQL 綜合教學

MySQL 連接查詢中索引的關鍵作用:從 75 秒優化到 0.07 秒的實戰分析

測試場景

  • 學生表 student:10,000 行,主鍵 student_id
  • 選課表 student_to_class:20,000 行,每生 2 門課,外鍵 student_id 無索引
  • 需求:左連接統計每生選課數

初始 SQL 與執行計劃

SELECT a.student_id, student_name, COUNT(*)
FROM student a
LEFT JOIN student_to_class b ON a.student_id = b.student_id
GROUP BY a.student_id;
EXPLAIN 结果:
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows  | Extra                                        |
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+
|  1 | SIMPLE      | a     | ALL  | NULL          | NULL | NULL    | NULL | 10649 | Using temporary; Using filesort              |
|  1 | SIMPLE      | b     | ALL  | NULL          | NULL | NULL    | NULL | 20287 | Using where; Using join buffer (Block Nested)|
+----+-------------+-------+------+---------------+------+---------+------+-------+----------------------------------------------+

現象: 兩表均 type=ALL 全表掃描,驅動表 1 萬行 × 被驅動表 2 萬行 = 2 億次比較,耗時 75.467 秒。

優化:給被驅動表連接列加索引

ALTER TABLE student_to_class ADD INDEX idx_student_id (student_id);

優化後執行計劃

EXPLAIN 结果:
+----+-------------+-------+------+---------------+-----------------+---------+------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key             | key_len | ref  | rows | Extra                                        |
+----+-------------+-------+------+---------------+-----------------+---------+------+------+----------------------------------------------+
|  1 | SIMPLE      | a     | ALL  | NULL          | NULL            | NULL    | NULL | 10649| Using temporary; Using filesort              |
|  1 | SIMPLE      | b     | ref  | idx_student_id| idx_student_id  | 5       | func | 1    | Using where; Using index                     |
+----+-------------+-------+------+---------------+-----------------+---------+------+------+----------------------------------------------+

關鍵變化:

  • 被驅動表 type: ALL → ref
  • key: idx_student_id 生效
  • rows: 20287 → 1(每次驅動僅掃 1 行)
  • Using index 覆蓋索引,無需回表

效果對比

核心原理:Nested Loop Join (NLJ)


						
						
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
指標優化前優化後提升
執行時間75.467 s0.077 s980 倍
被驅動表掃描行數20,2871 (per loop)20,000 倍
連接算法Block Nested LoopIndex Nested Loop Join質變