900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 《MySQL——使用联合索引 覆盖索引 避免临时表的排序操作》

《MySQL——使用联合索引 覆盖索引 避免临时表的排序操作》

时间:2021-02-22 00:46:43

相关推荐

《MySQL——使用联合索引 覆盖索引 避免临时表的排序操作》

联合索引避免临时表排序

在上一篇笔记(MySQL——order by逻辑(全字段排序与rowid排序))中,讲到查询语句查询多个字段的时候使用order by语句实现返回值是有序的,而order by是使用到了临时表的,会带来时间和空间损失。

其实使用联合索引,就可以避免临时表的排序操作。

只要保证city这个索引上取出来的行天然就是按照name递增排序的话,就可以不用再排序了。

alter table t add index city_user(city,name);

在这个索引里面,通过树搜索的方式定位到第一个满足city = '杭州’的记录,并且额外确保了,接下来按顺序取“下一条记录”的遍历过程中,只要city值是杭州,name值一定有序。

查询流程变为:

1、从索引(city,name)找到第一个满足city = '杭州’条件的主键id;

2、到主键id索引取出整行,取name、city、age三个字段值,作为结果集的一部分直接返回

3、从索引(city,name)取下一个记录主键id;

4、重复step2、3直到查到第1000条记录,或者不满足city = '杭州’条件时循环结束。

覆盖索引优化查询

可以使用覆盖索引继续优化查询的执行流程:

覆盖索引指,索引上的信息足够满足查询请求,不需要再回到主键索引上取数据。

针对select city,name,age from t这个查询,可以创建一个city、name和age的联合索引,对应语句为:

alter table t add index city_user_age(city,name,age);

这时,对于city字段的值相同的行来说,还是按照name字段的值递增排序。查询语句的执行流程变为:

1、从索引(city,name,age)找到第一个满足city = '杭州’条件的记录,取出其中的city、name和age三个字段值,作为结果集的一部分直接返回

2、从索引(city,name,age)取下一个记录,同样取出这三个字段的值,作为结果集的一部分直接返回

3、重复步骤2,直到查到第1000条记录,或者是不满足city = '杭州’条件时循环结束。

当然,并不是说每个查询能用上覆盖索引,就要把语句中涉及的字段都建上联合索引。因为索引有维护代价。

思考

假设表里面已经有了city_name(city,name)联合索引。你需要查询杭州和苏州两个城市中所有市民的名字,并且按名字排序,显示前100条记录。

select * from t where city in('杭州','苏州') order by name limit 100;

这个语句会有排序。因为条件是苏州或杭州。如果只有一个条件如只有杭州,那么就不需要排序操作。

如果我们需要实现一个在数据库端不需要排序的方案,可以这么实现:

把这一条语句拆成两条语句,流程如下:

1、执行select * from t where city = '杭州' order by name limit 100;

(这个语句不需要排序,客户端用一个长度为100的内存数组A保存结果)

2、执行select * from where city = '苏州' order by name limit 100;

(相同的方法,结果被存入内存数组B)

3、对AB两个有序数组采用归并排序,得到name最小的前100值,这就是我们需要的结果了。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。