MySQL查询默认排序与order by排序

最近发现一个平时经常忽略的问题,就是MySQL查询出来的结果的排序问题。

之前一直认为,如果在sql语句中没有加特定的order by条件,那么查询出来的数据就应该是按照主键(即插入顺序)排序的。但是,今天在项目中拿数据时发现并没有按照“我以为”的方式排序,就研究了下,发现按照什么方式排序与所查询的字段、索引等都有关系的。

因为项目中基本都使用InnoDB引擎,所以就不考虑其他引擎了,自己测试了下:

首先创建测试表(随便写了下sql语句,不要细究什么没有判断表是否存在的问题,哈哈)

小心机一下,字段尽量不要允许为NULL

CREATE TABLE `test` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT '' NOT NULL,
  `age` int(5) DEFAULT 0 NOT NULL,
  PRIMARY KEY (`id`),
  KEY `age` (`age`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

插入一些测试数据

INSERT INTO test(name, age) VALUES('张三',2);
INSERT INTO test(name, age) VALUES('李四',20);
INSERT INTO test(name, age) VALUES('王五',50);
INSERT INTO test(name, age) VALUES('赵刘',33);
INSERT INTO test(name, age) VALUES('奔驰',19);
INSERT INTO test(name, age) VALUES('宝马',7);
INSERT INTO test(name, age) VALUES('奥迪',21);
INSERT INTO test(name, age) VALUES('雷车',22);
INSERT INTO test(name, age) VALUES('兰博',18);
INSERT INTO test(name, age) VALUES('宾利',99);
INSERT INTO test(name, age) VALUES('夏利',67);

测试1:无条件查询前5条记录

SELECT * FROM test LIMIT 5

结果如下

测试2:无条件查询前5条age

select age from test limit 5;

测试3:无条件查询前5条记录,结果集根据age排序

select * from test order by age;

分别使用explain命令对这三条sql语句进行分析:

可以看到:

第1、3两条select * 语句的type都是ALL,说明进行的是全表扫描,没有用到索引。(Using filesort情况该如何优化?)

第2条select age 语句的type是index,说明使用的索引进行的扫描;且key是age,说明使用的索引列是age。

 

总结:

如果在sql语句中不指定order by排序条件,那么得到的结果集的排序顺序是与查询列有关的。因为不同的查询列可能会用到不同的索引,从而导致顺序不同。根据上面的情况:查询所有列时是根据id排序的;只查询age列时是根据age列(age列是索引)排序的;而加上order by age后,因为待排序内容不能由所使用的索引直接完成排序,所以要进行文件排序,具体原因就不深究了。

看网上大神的说法是:没有条件的情况下,数据库默认排序顺序是不好确定的,也不应该决定于什么因素,不同的数据库实现不同.只能用order by 来限定。

反正,不要迷信mysql默认会按照你以为的顺序排序,想要排序就先给你想要排序的字段创建索引(提高效率),然后再order by这个字段进行排序。

 

 

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值