mysql 排序字段设计_mysql的sort by学习

前沿

学习了mysql的next-key-lock后,现在正式进入sort by的学习阶段。有时在项目里会用到sort by语句。我也听说sort by有可能会对mysql造成压力,所以要学习一下sort by的过程,从而才能深刻的了解自己的sort by语句对mysql的压力,避免线上性能低下或者事故。

场景

有这么一个场景,要对杭州市民按照姓名排序,取前1000个人。

给city加索引,表设计如下:

1 CREATE TABLE `t` ( `id` int(11) NOT NULL,2 `city` varchar(16) NOT NULL,3 `name` varchar(16) NOT NULL,4 `age` int(11) NOT NULL,5 `addr` varchar(128) DEFAULT NULL,6 PRIMARY KEY(`id`),7 KEY `city` (`city`)) ENGINE=InnoDB;

然后执行:

1 select city,name,age from t where city=‘杭州‘ order by name limit 1000 ;

全字段排序

那接下来引擎层是如何执行的呢?大致过程如下:

1、初始化该sql线程的sort buffer,其大小是sort buffer size决定的。

2、city索引上查找第一个city=‘杭州‘的记录,取出id

3、到主键索引取出select所需的三个字段:city、name和age,插入到sort buffer中;

4、然后继续在city索引上查找下一个记录,重复2、3步,直到city不等于‘杭州‘;

5、在sort buffer中按照name进行排序

6、取出前1000的记录,返回给用户

这边有一个问题,就是如果数据量太大,那么sort buffer不一定能放下。那此时就要借助磁盘辅助排序。mysql在这边做了优化,是将数据放到若干个小的临时文件中,先各自排序,然后合并成一个大的临时文件,应该是类似于归并排序吧。

上述排序的好处是读完原表中数据后只需借助sort buffer和临时文件排序就行了。

row id排序

还有一个问题,就是要返回的当行数据过大时,会导致sort buffer中放不了多少行数据,就不得不借助临时文件排序,影响性能。row id排序可以缓解这种情况。通过如下配置,告知mysql单行超过多大需要使用row id排序。

假设city, name, age三个字段有32字节,而我们设置超过16个字节就采用row id排序。

1 SET max_length_for_sort_data = 16;

row id排序过程大致如下:

1、初始化sort buffer,确定放入两个字段:name和id;

2、从索引 city 找到第一个满足 city=‘杭州’条件的主键 id

3、用主键id在主键索引中查找name字段

4、将id和name放入sort buffer中

5、索引中继续查找下一个满足条件的主键id,重复3、4步骤,直到遇到第一个不满足条件的记录。

6、在sort buffer中按name排序,取前1000个

7、回表,获取这1000个id对应的city和age,返回给用户。

这样做的好处是,同样大小的sort buffer可以放更多的记录,尽可能的在内存中完成操作,代价是会多一次回表取其余字段。

借助联合索引

如果选出来的结果是天然有序的,那么我们就不用再做额外排序了。因为索引是天然有序的,所以可以创建city和name的联合索引,这样选出来的结果自然是按照name排序的了

alter table t add indexcity_user(city, name);select name, age, city from t where city=‘杭州‘ limit 1000;

具体的执行过程就不分析了。如果想避免一次回表去读取age字段,也可以讲索引改成如下,这就是覆盖索引。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你的MySQL InnoDB表中,where字段有索引,但是在使用order by聚集索引进行排序时仍然很慢,可能是由于以下几个原因导致的: 1. 索引选择不当:虽然你的where字段有索引,但是在order by聚集索引排序时,可能没有使用到合适的索引。使用EXPLAIN语句来查看查询计划,确认是否使用了正确的索引。你可以尝试创建一个包含where字段排序字段的复合索引,以提高查询效率。 2. 数据量过大:如果表中的数据量非常大,即使有合适的索引,仍然可能导致排序操作变慢。考虑通过分页查询或者限制结果集的大小来减少排序的数据量。 3. 硬件性能问题:如果服务器硬件配置较低,例如内存不足或者磁盘IO性能不佳,也可能导致排序操作变慢。确保服务器具备足够的资源以支持高效的排序操作。 4. 查询优化:请检查SQL语句是否存在其他影响性能的因素,例如过多的关联表、不必要的数据类型转换等。优化查询语句可以提高整体性能。 5. 调整配置参数:针对InnoDB引擎,你还可以尝试调整一些相关的配置参数来优化排序操作。例如,增加sort_buffer_size参数的值,提高排序缓冲区的大小。 总之,解决MySQL InnoDB的where字段有索引,但是order by聚集索引排序很慢的问题,需要综合考虑索引选择、数据量、硬件性能、查询优化和配置参数等方面的因素。通过合理的索引设计、优化查询语句和调整配置参数,可以提高排序操作的性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值