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

MySQL 文件排序 vs 索引排序:原理、性能對比與優化實戰

     編輯:MySQL 綜合教學

MySQL 文件排序 vs 索引排序:原理、性能對比與優化實戰

核心概念

排序方式原理觸發條件性能特徵
索引排序利用索引有序性,按索引順序讀取,無需額外排序ORDER BY 列為索引最左前綴、排序方向一致、無篩選條件破壞順序零排序開銷、極快、EXPLAIN Extra 無 Using filesort
文件排序在內存/磁盤臨時表中對結果集排序無合適索引、ORDER BY 非索引列、混合 ASC/DESC、JOIN 後排序CPU 密集、可能落盤、EXPLAIN Extra 顯示 Using filesort

實驗驗證

表結構
CREATE TABLE artist (
  artist_id INT UNSIGNED PRIMARY KEY,
  type ENUM('Band','Person','Unknown','Combination') NOT NULL,
  name VARCHAR(255) NOT NULL,
  gender ENUM('Male','Female') DEFAULT NULL,
  founded YEAR DEFAULT NULL,
  country_id SMALLINT UNSIGNED DEFAULT NULL,
  UNIQUE KEY name (name)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
場景一:文件排序
EXPLAIN SELECT name, founded FROM artist WHERE name LIKE 'AUSTRALIA%' ORDER BY founded;
-- Extra: Using index condition; Using filesort

執行後查看會話狀態:

SHOW SESSION STATUS LIKE '%sort%';
-- Sort_range: 1, Sort_rows: 22 → 發生了排序操作
場景二:索引排序
EXPLAIN SELECT name, founded FROM artist WHERE name LIKE 'AUSTRALIA%' ORDER BY name;
-- Extra: Using index condition  (無 filesort)
SHOW SESSION STATUS LIKE '%sort%';
-- 所有排序計數器均為 0 → 無排序開銷

排序狀態變量解讀

變量含義調優參考
Sort_merge_passes歸併排序段數>0 表示 sort_buffer_size 不足,需增大
Sort_range範圍掃描排序次數索引範圍查詢後排序
Sort_rows排序總行數評估排序規模
Sort_scan全表掃描排序次數無索引全表排序

優化策略

  1. 建立合適索引:INDEX idx_name_founded (name, founded) 支援 WHERE name + ORDER BY founded
  2. 避免 SELECT *:只查詢所需列,減少排序行寬度,降低 sort_buffer 壓力
  3. 調大 sort_buffer_size:會話級,SET sort_buffer_size = 8M,但慎用(每連接分配)
  4. 使用 LIMIT:ORDER BY founded LIMIT 10 可觸發 Priority Queue 排序(MySQL 8.0+),僅維護 Top-N
  5. 強制索引:ORDER BY name ASC, founded DESC 混合方向無法用索引,嘗試統一方向或重建索引

進階:MySQL 8.0 排序優化

  • 即時排序:早期版本雙路排序(兩次 IO),5.6+ 單路排序(一次 IO,將所有列打包)
  • 優先隊列排序:ORDER BY ... LIMIT N 使用小頂堆,內存佔用 O(N) 而非 O(行數)
  • 排序緩衝區複用:並行查詢排序緩衝區可複用

排查檢查單

-- 1. 確認是否 filesort
EXPLAIN SELECT ... ORDER BY col;

-- 2. 查看排序規模
SHOW SESSION STATUS LIKE 'Sort_rows';

-- 3. 檢查索引是否可用
SHOW INDEX FROM table;

-- 4. 分析 sort_buffer 是否足夠
SHOW SESSION STATUS LIKE 'Sort_merge_passes';
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved