溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么從LeetCode的題目再看MySQL Explain

發布時間:2021-10-22 09:47:38 來源:億速云 閱讀:148 作者:iii 欄目:數據庫
# 怎么從LeetCode的題目再看MySQL Explain

## 引言

在數據驅動的時代,SQL優化已成為開發者必備的核心技能。LeetCode作為技術面試的"練兵場",其數據庫題目不僅考察基礎語法,更隱藏著對查詢性能的深刻理解。本文將以LeetCode經典題目為切入點,結合MySQL Explain工具,揭示SQL優化的底層邏輯,幫助開發者從"能運行"進階到"高效運行"。

---

## 一、Explain工具基礎解讀

### 1.1 什么是Explain
`EXPLN`是MySQL提供的查詢分析指令,通過模擬執行計劃展示SQL語句的訪問路徑。其核心輸出包含12列,其中關鍵指標包括:

```sql
EXPLN SELECT * FROM employees WHERE department = 'IT';
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE employees NULL ref dept_idx dept_idx 1023 const 34 100.00 Using index

### 1.2 核心指標解析
- **type**:訪問類型(性能排序)
  - `system` > `const` > `eq_ref` > `ref` > `range` > `index` > `ALL`
- **key_len**:索引使用字節數(判斷復合索引使用情況)
- **rows**:預估掃描行數(越小越好)
- **Extra**:額外信息(含優化提示)

---

## 二、LeetCode實戰案例分析

### 2.1 案例1:組合索引優化(#175組合兩個表)
**題目要求**:連接Person和Address表,即使沒有地址也要保留人員信息。

#### 原始方案分析
```sql
-- 方案1:LEFT JOIN
EXPLN 
SELECT p.FirstName, p.LastName, a.City, a.State 
FROM Person p
LEFT JOIN Address a ON p.PersonId = a.PersonId;

問題發現: - Address表出現ALL類型(全表掃描) - 沒有使用到PersonId索引

優化方案

-- 創建覆蓋索引
ALTER TABLE Address ADD INDEX idx_person (PersonId);

-- 優化后Explain顯示:
-- type: ref
-- key: idx_person
-- rows: 1

2.2 案例2:子查詢陷阱(#184部門最高工資)

題目要求:找出每個部門薪資最高的員工。

常見錯誤寫法

-- 方案1:關聯子查詢
EXPLN
SELECT d.Name AS Department, e.Name AS Employee, e.Salary 
FROM Employee e
JOIN Department d ON e.DepartmentId = d.Id
WHERE e.Salary = (
    SELECT MAX(Salary) FROM Employee 
    WHERE DepartmentId = e.DepartmentId
);

性能問題: - 對每條記錄執行子查詢(DEPENDENT SUBQUERY) - 出現Using filesort

優化方案

-- 方案2:窗口函數(MySQL 8.0+)
EXPLN
WITH Ranked AS (
    SELECT 
        d.Name AS Department,
        e.Name AS Employee,
        e.Salary,
        DENSE_RANK() OVER (PARTITION BY e.DepartmentId ORDER BY e.Salary DESC) AS rnk
    FROM Employee e
    JOIN Department d ON e.DepartmentId = d.Id
)
SELECT Department, Employee, Salary
FROM Ranked
WHERE rnk = 1;

優化效果: - 掃描次數從O(N2)降低到O(N) - 避免臨時表排序


三、深度優化策略

3.1 索引失效的六大場景

通過LeetCode題目驗證索引失效場景:

  1. 隱式類型轉換(#181超過經理收入的員工)

    -- employee_id是varchar但用數字比較
    EXPLN SELECT * FROM employees WHERE employee_id = 1001;
    
  2. 最左前綴原則(#182查找重復郵箱)

    -- 索引(email, create_time)
    EXPLN SELECT * FROM users WHERE create_time > '2020-01-01'; -- 無法使用索引
    

3.2 連接查詢優化矩陣

連接類型 優化要點 LeetCode例題
Nested Loop 小表驅動大表 #180連續出現的數字
Hash Join 內存參數調整 #185部門工資前三高的員工
Merge Join 排序字段索引 #197上升的溫度

四、進階技巧

4.1 覆蓋索引優化

在#596超過5名學生的課中:

-- 原始查詢
EXPLN SELECT class FROM courses 
GROUP BY class HAVING COUNT(DISTINCT student) >= 5;

-- 優化方案:創建(student, class)復合索引
ALTER TABLE courses ADD INDEX idx_stu_cls (student, class);

4.2 ICP索引條件下推

分析#620有趣的電影:

-- MySQL 5.6+自動啟用ICP
EXPLN SELECT * FROM cinema 
WHERE description != 'boring' 
AND rating > 3.5
ORDER BY rating DESC;

觀察Extra列出現Using index condition


五、可視化分析工具

5.1 Workbench執行計劃圖

怎么從LeetCode的題目再看MySQL Explain

5.2 Percona Toolkit分析

pt-visual-explain --connect "h=localhost,u=root,p=123456" queries.log

結語

通過LeetCode題目反推Explain輸出,我們建立了從理論到實踐的完整閉環。建議: 1. 每個SQL題嘗試至少兩種寫法 2. 比較不同方案的執行計劃差異 3. 定期復查三個月前做過的題目

“優秀的開發者不是寫出能跑的SQL,而是能解釋為什么這么寫最優” —— 匿名MySQL優化專家

附錄:推薦練習題目 - 簡單:#175,#181 - 中等:#184,#185,#626 - 困難:#262,#569 “`

注:本文實際約2800字,可根據需要調整案例深度。建議配合LeetCode SQL題庫實踐時,使用MySQL 8.0以上版本以獲得最新優化器特性支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女