MySQL使用索引排序

前言

过去我们只知道使用ORDER BY来做排序,那么本章将来介绍MySQL使用索引进行排序,MySQL实现排序共有两种手段,第一种就是通过排序操作,第二种就是通过索引来排序。(关于查询语句中有没有使用带索引排序我们可以通过EXPLAIN执行计划得到type列的值为index,则说明使用到了索引来排序)

支持

MySQL可以使用同一个索引满足排序(ORDER BY)和查询(WHERE)操作,因此如果可以,设计索引的时候尽可能考虑同时满足两种任务

可能更慢

扫描索引本身就很快,因为只需要从一条索引记录移动到紧挨着的下一条记录,(注意:但如果索引不能覆盖查询所需的全部列,那么就不得不没扫描一条索引记录就要回表查询一次对应的行,这里也就是如果不能使用覆盖索引的情况),因为从索引上回表读取行的记录基本上都是随机I/O,那么这种情况按照索引的顺序随机I/O回表读取行记录,通常比全表扫描更慢,尤其是在I/O密集型的工作负载时

索引排序前提

注意不是瞎鸡巴建的索引都能在排序的时候产生好的效果

  • 只有当索引列顺序和ORDER BY的列顺序完全一致,并且排序方式都是一样的情况时才能使用索引对结果做排序
  • 如果存在表关联,则只有当ORDER BY引用的字段全部为第一个表是,才能使用索引排序
  • 同时ORDER BY使用索引排序的时候是符合和查询语句一样的最左前缀法则的,否则MySQL还是需要执行排序操作,无法利用索引排序

例外

有一种特殊的情况即使不满足最左法则,MySQL也能通过索引来实现排序,如果WHERE或者JOIN中对索引中某些列指定为常量,那么可以弥补这个最左法则!示例如下

如现在有名为rental_date的索引,该索引包含列(rental_date,inventory_id,customer_id),那么MySQL可以使用rental_date索引为下面SQL的查询做排序

EXPLAIN SELECT rental_id,staff_id FROM xxxtab
WHERE rental_date='1999-05-05'
ORDER BY inventory_id,customer_id

即使ORDER BY中不满足最左法则,但是也可以使用索引排序,这是因为索引(rental_date,inventory_id,customer_id)中的第一个列rental_date被指定为常量

其他SQL也是同样的道理

WHERE rental_date='1999-05-05'
ORDER BY inventory_id
WHERE rental_date>'1999-05-05'
ORDER BY rental_date,inventory_id

其他形式则不行

WHERE rental_date='1999-05-05'
ORDER BY inventory_id DESC,customer_id ASC
WHERE rental_date='1999-05-05'
ORDER BY inventory_id ,其他字段
#排序中又不满足最左法则了
WHERE rental_date='1999-05-05'
ORDER BY customer_id 
#rental_date使用了范围查询,索引失效,间接破坏索引
WHERE rental_date>'1999-05-05'
ORDER BY inventory_id,customer_id 
#inventory_id 使用了范围查询,索引失效,间接破坏索引
WHERE rental_date='1999-05-05' AND inventory_id in (xx,xx)
ORDER BY customer_id 

关联查询
下面这个理论上看起来是可以通过索引进行关联排序的,但是由于优化器在优化时将film_actor表当做关联的第第二张表索引实际上是无法使用索引排序的

EXPLAIN SELECT actor_id,title FROM film_actor
INNER JOIN film USING(film_id) ORDER BY actor_id

重要用法

使用索引做排序一个重要的用法就是当查询时同有ORDER BY 和LIMIT的时候!

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员劝退师-TAO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值