(1)回顾:
之前说了在SQL使用where语句进行数据过滤和筛选的时候,在where语句里要如何写才能用上我们建立好的索引,其实无论是那条规则,尽可能从联合索引最左侧的字段开始使用,就能用上索引树。
(2)order by排序如何用上索引?
假如 SQL语句 select from table where xxx = xxx order by xxx 这样的一个SQL语句,似乎是基于where语句通过索引快速筛选出一波数据,接着放到内存里,或者放在一个临时磁盘文件里,然后通过排序算法按照某个字段排序,把排好序的数据返回,但是这样比较慢,尤其是当排序的数据量比较大的话,还不能用内存来排序,如果基于磁盘文件来排序,那在MySQL里有一个术语,叫做 filesort ,这速度就慢了,通常不这样做,尤其是 select from tabel order by xx1,xx2,xx3 limit 100 这样的SQL语句,按照多个字段排序然后返回排名前100条数据,类似的语句常见于分页SQL语句里,需要对表里数据进行排序,然后limit拿出来指定部分的数据。
这种情况下,假设建立 INDEX(xx1,xx2,xx3)这样的联合索引,这个时候默认情况下,在索引树里本身就是依次按照xx1,xx2,xx3 三个字段的值去排序的,此时再运行select * from table order by xx1,xx2,xx3 limit 100这样的SQL语句,显然是不会在临时磁盘文件里排序的。因为这也是按照xx1,xx2,xx3 三个字段来进行排序罢了,在联合索引的索引树里都排好序了,直接按照索引树里的顺序,把xx1,xx2,xx3 三个字段按照从小到大的值获取前面100条就可以了。然后拿到100条数据的主键再去聚簇索引里回表查询剩余所有的字段。
所以说,在SQL语句里,应该尽量按照联合索引的字段顺序进行order by 排序,这样就可以直接利用联合索引树的数据有序性,到索引里直接按照字段值的顺序获取需要的数据。但是有一些限定规则,因为联合索引里的字段值在索引树里都是从小到大依次排列的,所以在order by里要不然每个字段后面什么都不加,直接就是order by xx1,xx2,xx3,要不然都加DESC降序,order by xx1,xx2,xx3 DESC,不能order by 语句里有的字段升序有的字段降序,那就使用不到索引了。
另外,要是order by语句里有的字段不在联合索引里,或者对order by语句里的字段用了复杂的函数,这些也使用不了索引排序。