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
发布了97 篇原创文章 · 获赞 59 · 访问量 29万+

猜你喜欢

转载自blog.csdn.net/b1303110335/article/details/82976133