order by关键字排序优化

 一、MySQL排序分类

#1.通过索引扫描生成有序的结果

#2.使用文件排序(filesort)

 

1、索引扫描执行过程

#SQL语句中,WHERE子句和ORDER BY子句都可以使用索引:
    WHERE子句使用索引避免全表扫描,ORDER BY子句使用索引避免filesort(用“避免”可能有些欠妥,某些场景下全表扫描、filesort未必比走索引慢),以提高查询效率。
            (索引既有查询的能力,也有排序的功能)

虽然索引能提高查询效率,但在一条SQL里,对于一张表的查询 一次只能使用一个索引,也就是说当WHERE子句与ORDER BY子句要使用的索引不一致时,MySQL只能使用其中一个索引(B+树)

#一个既有WHERE又有ORDER BY的SQL中,使用索引有三个可能的场景:
    1、只用于WHERE子句 筛选出满足条件的数据

    2、只用于ORDER BY子句 返回排序后的结果

    3、既用于WHERE又用于ORDER BY,筛选出满足条件的数据并返回排序后的结果

 

#MySQL能为排序与查询使用相同的索引
-------------------------------------------------
key a_b_c(a,b,d)

#order by 能使用索引的
order by a
order by a,b
order by a,b,c
order by a DESC,b DESC,c DESC


#如果where使用索引的最左最左前缀定义为变量,则 order by能使用索引
where a = const order by b,c
where a = const and b = const order by c
where a = const and order by b,c
where a = const and b>const order by b,c    #b>const,order by必须有b


#不能使用索引进行排序的
where d = const order by b,c       #没有火车头
where a = const order by c          #没有B,中间车厢断开
where a = const order by a,d       #d不是索引的一部分
where a in (..)order by b,c        #对于排序说,多个相等条件也是范围查询

 

练习

create table tb2(
    age int,
    birth timestamp not null);

insert into tb2(age,birth) values(20,now());
insert into tb2(age,birth) values(21,now());
insert into tb2(age,birth) values(22,now());

create index idx_A_B on tb2(age,birth);
需要的表

 

 

 

 

 

2、文件排序

#人误以为它会:将一张非常大的表放入磁盘再进行排序,filesort仅仅是排序而已,filesort是否会使用磁盘取决于它操作的数据量大小

#总结来说就是,filesort按排序方式来划分 分为两种:
    1.数据量小时,在内存中快排

    2.数据量大时,在内存中分块快排,再在磁盘上将各个块做归并(涉及到磁盘IO)


#根据回表查询的次数,filesort又可以分为两种方式:

    1.回表读取两次数据(two-pass):两次传输排序

    2.回表读取一次数据(single-pass):单次传输排序

 

posted @ 2019-06-24 17:30  pdun  阅读(1258)  评论(0编辑  收藏  举报