在MySQL中,可以指定按照多个字段进行排序。例如,可以使employee表按照d_id字段和age字段进行排序。排序过程中,先按照d_id字段进行排序,遇到d_id字段的值相等的情况时,再把d_id值相等的记录按照age字段进行排序。
创新互联公司专注于企业营销型网站、网站重做改版、邱县网站定制设计、自适应品牌网站建设、H5开发、购物商城网站建设、集团公司官网建设、成都外贸网站建设公司、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为邱县等各大城市提供网站开发制作服务。
查询employee表中的所有记录,按照d_id字段的降序方式和age字段的升序方式进行排序。
前几天工作上遇到一个问题,在mysql数据查询的时候,使用的是in条件,而结果需要根据in来进行排序,当时尝试了几次都没成功,后来在度娘的帮助下,找到了解决办法:
select * from table_name where id in (6,2,1,10,5,7..)
查询的结果和in中的顺序并不一致,也就是说在批量查询时,mysql的查询并不是按照in中的值得顺序来查询的。那怎么才能保证和in查询中的顺序相同呢?
查询了资料发现有两种方式可以对in查询的结果进行排序。一种是order by find_in_set,另外一种是order by substring_index
1、select * from table_name where id in (6,2,1,10,5,7..) order by find_in_set(id,'6,2,1,10,5,7');
2、select * from table_name where id in (6,2,1,10,5,7..) order by substring_index('6,2,1,10,5,7',id,1);
对结果进行排序操作的代价可能很高,因此可以通过避免排序或让参与排序的数据行更少来优化查询性能。
当 MySQL 不能使用索引产生有序结果时,它必须对数据行进行排序。这有可能是在内存中进行也可能是在磁盘进行,但 MySQL 始终将这个过程称之为 filesort,即便实际上并没有使用一个文件。
如果用于排序的值可以一次性放入排序缓存中,MySQL 可以在内存中使用快排算法进行排序。如果 MySQL 不能在内存中进行排序,则会在磁盘中按块逐块排序。它对每个块使用快排算法,然后在将这些排序好的块合并到结果中。
有两个文件排序(filesort)算法:
很难说哪种算法更有效,对每个算法来说都会有最优和最坏案例。MySQL 在数据表全部列加上用于排序的列的大小不超过 max_length_for_sort_data 时会使用单次遍历算法。可以通过修改这个参数影响排序算法的选择。
需要注意的是,MySQL 的 filesort使用的临时存储空间可能会超出你的预期,这是因为它对每个排序元素都分配了固定大小的存储空间。这些存储空间要足够大以便容下存储最大的元素,而且 VARCHAR这类字段使用的是对应的最大长度。而且,如果使用的是 UTF-8字符集,MuSQL 会对每个字符分配3个字节。结果是,我们会发现那些没怎么优化的查询会导致磁盘上的临时存储空间是数据表自身存储空间的好几倍。
而在对联合查询进行排序时,MySQL 可能会在查询执行过程中执行两次文件排序。如果 ORDER BY 子句只是引用联合查询的第一张表,MySQL 可以先对这个表进行文件排序,然后再处理联合查询。如果是这种情况,在 EXPLAIN 时会在 Extra 字段显示“Using filesort”。而对于其他的排序情况——例如排序不是针对第一张表,或者是 ORDER BY 使用的列对应了不止一个数据表,MySQL 必须使用临时表缓存查询结果,然而在联合查询完成后,再对临时表进行文件排序。在这种情况下,EXPLAIN 会在 Extra 字段显示“Using temorary; Using filesort”。如果包含 LIMIT 约束的话,会发生在文件排序后,因此临时表和文件排序的存储空间可能非常大。
MySQL 5.6在只需要对数据行的子集(例如 LIMIT)进行排序时,引入了一个重大改进。相对于对整个结果集进行排序再返回部分数据,MySQL 有时候会在排序的时候直接丢弃掉不需要的数据行来提高效率。不管怎么样,排序也需要小心使用,很可能会导致存储占用的飙升最终导致系统负荷过大。