1. 程式人生 > >mysql order by索引分析

mysql order by索引分析

這裡主要討論一下InnoDB B-Tree索引的使用,不提設計,只管使用。B-Tree索引主要作用於WHERE和ORDER BY子句。這裡討論的均在MySQL-Server-5.7.23測試

CREATE TABLE `friends` ( `ID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT, `uid`bigint(20) UNSIGNED NOT NULL DEFAULT '0', `fuid` bigint(20) UNSIGNED NOT NULL DEFAULT'0', `fname` varchar(50) NOT NULL DEFAULT '', `fpicture` varchar(150) NOT NULL DEFAULT'', `fsex` tinyint(1) NOT NULL DEFAULT '0', `status` tinyint(1) NOT NULL DEFAULT '0',PRIMARY KEY (`ID`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ALTER TABLE`friends` ADD INDEX uid_fuid (uid, fuid);
-- ORDER BY滿足以下情況,會使用Index方式排序:
--  a)ORDER BY 語句使用索引最左前列。參見第1句
-- 	b)使用Where子句與Order BY子句條件列組合滿足索引最左前列。
EXPLAIN SELECT uid FROM friends ORDER BY uid DESC;

-- 檢查的行數過多,且沒有使用覆蓋索引。第3句,雖然跟第2句一樣,order by使用了索引最左前列uid,但依然使用了filesort方式排序,因為status並不在索引中,所以沒辦法只掃描索引。
EXPLAIN SELECT uid,`status` FROM friends ORDER BY uid;

-- 使用了不同的索引,MySQL每回只採用一個索引.第4句,order by出現二個索引,分別是uid_fuid和聚集索引(pk)
EXPLAIN SELECT uid FROM friends ORDER BY uid,ID DESC;

-- 對索引列同時使用了ASC和DESC
EXPLAIN SELECT uid FROM friends ORDER BY uid ASC, fuid DESC;

-- where uid取出排序需要的資料,MySQL將其轉為常量,它的ref列為const。
EXPLAIN SELECT uid,`status` FROM friends WHERE uid = 6887 ORDER BY uid asc, fuid DESC;

-- where語句與order by語句,使用了不同的索引
EXPLAIN SELECT uid,`status` FROM friends WHERE uid = 1 ORDER BY ID;

-- where語句或者ORDER BY語句中索引列使用了表示式,包括函式表示式(abs)
EXPLAIN SELECT uid,`status` FROM friends WHERE uid - 1 = 6887 ORDER BY uid asc;

-- where 語句與ORDER BY語句組合滿足最左字首,但where語句中使用了條件查詢。查見第10句,雖然where與order by構成了索引最左有綴的條件,但是where子句中使用的是條件查詢。
EXPLAIN SELECT uid,`status` FROM friends WHERE uid > 6887 ORDER BY fuid asc;

-- order by子句中加入了非索引列,且非索引列不在where子句中。
EXPLAIN SELECT uid,`status` FROM friends WHERE uid = 1 ORDER BY `status`;

-- order by或者它與where組合沒有滿足索引最左前列。參見第11句和12句,where與order by組合,不滿足索引最左前列. (uid, fsex)跳過了fuid
EXPLAIN SELECT uid,`status` FROM friends WHERE uid = 1 ORDER BY `fsex`;
EXPLAIN SELECT uid FROM friends ORDER BY uid,`fsex`;

-- 當使用left join,使用右邊的表字段排序。參見第13句,儘管user.uid是pk,依然會使用filesort排序。
EXPLAIN SELECT f.uid,f.`status` FROM friends f LEFT JOIN user as u on f.uid = u.id WHERE f.uid = 123 order by u.id