mysql 的排序
1.indexsort 利用有序索引获取有序数据
原理:
我们知道,mysql的基础数据结构是B+树,任何的一个表都是一颗B+树,你在表上建的索引也是一颗B+树,B+树的特别是在叶子节点上是有序,且前一个节点存在指向相邻节点的指针。
那么在写SQL中的ORDER BY语句时候,若是ORDER BY的条件和返回的数据都在一颗树上,那么就可以利用B+树自身的特点来天然排序了,自然效率会比较高。
使用条件:
1)查询的WHERE子句和ORDER BY子句中查询的字段在同一颗索引树上,
2)ORDER BY 字段的顺序是跟建立索引的顺序是一致的。
3)查询的字段也在同一颗索引树
以上三个条件必须同时满足
2.filesort 文件排序
原理:
这里的文件排序并不是字面那表示的意思,利用了磁盘IO来进行排序,不过是优化器告诉你,进行了一个排序操作,具体排序的地方还是内存,相对应的参数是sort_buffer_size 设定的大小
1)filesort不一定会产生临时表
2)filesort 与临时表数据写入磁盘是没有任何直接联系
使用情景:
任何非索引排序的场景下
3.实战:
CREATE TABLE `A_index` (
`c1` INT(11) NOT NULL AUTO_INCREMENT ,
`c2` SMALLINT(2) ,
`c3` VARCHAR(16) ,
`c4` VARCHAR(16) ,
`c5` VARCHAR(16) ,
PRIMARY KEY (`c1`),
KEY `c2_ind` (`c2`),
KEY `c3_c4_c5_ind` (`c3`,`c4`,`c5`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
1)查询的字段和ORDER BY 字段在同一个索引树中:
mysql> EXPLAIN SELECT c3 FROM A_index ORDER BY c3 ,c4 ,c5 ;
+----+-------------+---------+-------+---------------+--------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+--------------+---------+------+------+-------------+
| 1 | SIMPLE | A_index | index | NULL | c3_c4_c5_ind | 153 | NULL | 1 | Using index |
+----+-------------+---------+-------+---------------+--------------+---------+------+------+-------------+
1 row in set (0.02 sec)
2)查询的字段和where 及 order by 中的字段在同一颗树中
mysql> EXPLAIN SELECT c3 FROM A_index where c3="1" ORDER BY c3 ,c4 ,c5 ;
+----+-------------+---------+------+---------------+--------------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+--------------+---------+-------+------+--------------------------+
| 1 | SIMPLE | A_index | ref | c3_c4_c5_ind | c3_c4_c5_ind | 51 | const | 1 | Using where; Using index |
+----+-------------+---------+------+---------------+--------------+---------+-------+------+--------------------------+
1 row in set (0.00 sec)
对于上面的差别是做了一次回表
3)where 及 order by 中的字段不在同一颗树中
mysql> EXPLAIN SELECT c3 FROM A_index where c2=1 ORDER BY c3 ,c4 ,c5 ;
+----+-------------+---------+------+---------------+--------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+--------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | A_index | ref | c2_ind | c2_ind | 3 | const | 1 | Using where; Using filesort |
+----+-------------+---------+------+---------------+--------+---------+-------+------+-----------------------------+
1 row in set (0.01 sec)
在两颗索引树中后,就走的是filesort了。
4)查询的字段和ORDER BY 字段不在同一个索引树中:
mysql> EXPLAIN SELECT c2 FROM A_index ORDER BY c3 ,c4 ,c5 ;
+----+-------------+---------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | A_index | ALL | NULL | NULL | NULL | NULL | 1 | Using filesort |
+----+-------------+---------+------+---------------+------+---------+------+------+----------------+
1 row in set (0.00 sec)
5)查询的字段和ORDER BY 字段在同一个索引树中,但是order by 顺序不同
mysql> EXPLAIN SELECT c3 FROM A_index ORDER BY c4 , c3 ,c5 ;
+----+-------------+---------+-------+---------------+--------------+---------+------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+-------+---------------+--------------+---------+------+------+-----------------------------+
| 1 | SIMPLE | A_index | index | NULL | c3_c4_c5_ind | 153 | NULL | 1 | Using index; Using filesort |
+----+-------------+---------+-------+---------------+--------------+---------+------+------+-----------------------------+
1 row in set (0.00 sec)
看到排序使用的是filesort,对于c3的查找用的是索引
4.优化filesort
从上面的索引排序使用限制上可以看出,我们大部分的业务场景应该是在filesort下,那么就该想着如何优化filesort。
filesort的两种排序算法:
双路排序
1)取出所有排序的字段及对应行数据的指针信息(指向具体的叶子节点数据)
2)在内存中进行排序
3)再通过指针取得具体的数据
单路排序
1)去除所有排序的字段及所有行信息
2)在内存中进行排序
两种的差别在于第一种需要两次磁盘IO,而第二种只需要一次,但第二种需要更大的内存开销。
优化器如何选择主要是根据 max_length_for_sort_data 系统参数设置的大小
mysql> show variables like '%max_length%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| max_length_for_sort_data | 1024 |
+--------------------------+-------+
1 row in set (0.00 sec)
若是查询出来的数据大小 > max_length_for_sort_data ,那么使用双路排序
若是查询出来的数据大小 < max_length_for_sort_data ,那么使用单路排序
相关推荐
activiti5.9修复mysql order by 排序bug 详情见博客地址:http://blog.csdn.net/qq413041153/article/details/7740773#comments
MySQL中的ORDER BY排序与索引关系是数据库性能优化的关键因素之一。本文主要针对InnoDB存储引擎的B-Tree索引进行探讨,不涉及索引设计,而是关注如何有效利用索引来提升查询性能。 首先,遵循**最左前缀法则**是...
在MySQL中,我们可以利用`CASE WHEN`来实现自定义排序,以满足特定的业务需求。以下是一个关于如何在MySQL排序中使用`CASE WHEN`方法的详细说明。 ### 1. `CASE WHEN` 基本语法 `CASE WHEN` 的基本语法如下: ```...
在这个例子中,`@OrderBy`注解使得Hibernate在查询`Article`时,根据`title`字段的GBK中文排序规则进行排序。 另外,提供的`GBKOrder.java`文件可能是实现自定义排序策略的类。在Hibernate中,可以通过实现`...
MySQL的`ORDER BY`和`GROUP BY`子句在执行查询时,对于性能的影响是显著的,尤其是在大数据量的表中。为了提高查询效率,索引优化显得至关重要。本文将详细介绍如何利用索引来优化`ORDER BY`操作。 首先,MySQL在...
select areaName from area order by convert(areaName USING gbk) COLLATE gbk_chinese_ci asc 说明:areaName为列名 area为表名 PS:这里再为大家推荐一款本站的相关在线工具供大家参考: 在线中英文根据首字母...
mysql 中order by 与group by的顺序是:selectfromwheregroup byorder by注意:group by 比order by先执行,order by不会对group by 内部进行排序,如果group by后只有一条记录,那么order by 将无效。要查出group ...
问题的描述是这样的:当我们使用 ORDER BY 对某个字段进行排序,然后使用 LIMIT 限制返回的记录数时,如果排序字段有相同的值,MySQL 会随机选取这些行,而不是按照正常的排序顺序返回记录。这是一个非常隐蔽的坑,...
在MySQL数据库中,`ORDER BY`子句用于对查询结果进行排序。在处理多字段排序时,MySQL遵循特定的规则来确定数据的排列顺序。本文将深入探讨这些规则,并通过代码示例进行解释。 首先,单字段排序是相对简单的。假设...
本文就和大家一起深入研究下mysql中group by与order by.下面是我模拟我的内容表 我现在需要取出每个分类中最新的内容 select * from test group by category_id order by `date` 结果如下 明显。这不是我想...
创建表&创建索引 ...MySQL也能利用索引来快速地执行ORDER BY和GROUP BY语句的排序和分组操作。 通过索引优化来实现MySQL的ORDER BY语句优化: 1、ORDER BY的索引优化 如果一个SQL语句形如: SELECT
–按某一字段分组取最大(小)值所在行的数据 代码如下: /* 数据如下: nameval memo a 2 a2(a的第二个值) a 1 a1–a的第一个值 a 3 a3:a的第三个值 b 1 b1–b的第一个值 b 3 b3:b的第三个值 b 2 b2b2b2b2 b 4 b4b4 b ...
本篇文章将详细介绍如何在 MySQL 中使用 `ORDER BY` 进行数据排序,并通过实例进行说明。 #### 基本语法 `ORDER BY` 子句的基本语法如下: ```sql SELECT column_name FROM table_name ORDER BY column_name [ASC...
在MySQL中,`COUNT()`, `GROUP BY`, 和 `ORDER BY` 是三个非常重要的SQL语句组成部分,它们各自承担着不同的职责,同时也常被结合在一起使用以满足复杂的数据查询需求。 `COUNT()` 是一个聚合函数,它用于计算指定...
MySQL中的`ORDER BY`和`GROUP BY`是SQL查询中两个关键的子句,它们用于对查询结果进行排序和分组。然而,在某些情况下,MySQL可能会使用`Using filesort`来完成这些操作,这通常会导致性能下降。本文将深入探讨`...
在MySQL数据库中,ORDER BY、GROUP BY 和 HAVING 子句是SQL查询中用于数据处理的关键组成部分,它们各自承担不同的任务,以帮助我们从数据库中提取有用的信息。 ORDER BY 子句主要用于对查询结果集进行排序。当你...
总之,`ORDER BY`和`LIMIT`是MySQL中用于数据排序和分页的关键工具,理解它们的用法并注意性能优化,能有效提升数据库查询的效率和用户体验。在实际应用中,应结合具体场景选择合适的排序和分页策略,以达到最佳效果...
计算机后端-PHP视频教程. php与mysql加强- 07. php加强16-order by排序.wmv
首先先按某个字段进行order by,然后把有顺序的表进行分组,这样每组的成员都是有顺序的,而mysql默认取得分组的第一行。从而得到每组的最值。 select id, (@rowno := @rowno + 1) as rank, score, (C.end_ti