前两天在工作中遇到一个Mysql排序的问题,在没有加order by的时候,获取的数据顺序是随机的,而不是按照主键排序的。以往我都以往mysql的排序默认是按主键来排序的。这才发现其实不是这样的。
CREATE TABLE `test` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` char(100) DEFAULT NULL,
`age` char(5) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `age` (`age`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
创建一个测试数据库
INSERT INTO test VALUES(NULL,'张三','5');
INSERT INTO test VALUES(NULL,'李四','15');
INSERT INTO test VALUES(NULL,'王五','5');
INSERT INTO test VALUES(NULL,'赵信','15');
INSERT INTO test VALUES(NULL,'德玛','20');
INSERT INTO test VALUES(NULL,'皇子','5');
INSERT INTO test VALUES(NULL,'木木','17');
INSERT INTO test VALUES(NULL,'好汉','22');
INSERT INTO test VALUES(NULL,'水浒','18');
INSERT INTO test VALUES(NULL,'小芳','17');
INSERT INTO test VALUES(NULL,'老王','5');
按照正常的主键递增的顺序插入一些数据SELECT * FROM test LIMIT 5
,然后查询五条记录
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | 张三 | 5 |
| 2 | 张三 | 5 |
| 3 | 李四 | 15 |
| 4 | 王五 | 5 |
| 5 | 赵信 | 15 |
+----+------+------+
5 rows in set (0.00 sec)
现在我们只查询两个字段,id,age select id,age from test limit 5
;
+----+------+
| id | age |
+----+------+
| 3 | 15 |
| 5 | 15 |
| 8 | 17 |
| 11 | 17 |
| 10 | 18 |
+----+------+
5 rows in set (0.00 sec)
这个时候可以看到 两次没有使用order by
得到的查询结果并不一样。这个时候我们来分析下查询语句
mysql> explain select * from test limit 5 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 12
Extra:
1 row in set (0.00 sec)
mysql> explain select id,age from test limit 5 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: test
type: index
possible_keys: NULL
key: age
key_len: 16
ref: NULL
rows: 12
Extra: Using index
1 row in set (0.00 sec)
可以看出,第一个查询语句是没有使用到任何的索引的,而第二个查询则是使用了age
作为索引。
最后
可以看出,mysql在不给定order by条件的时候,得到的数据结果的顺序是跟查询列有关的。因为在不同的查询列的时候,可能会使用到不同的索引条件。Mysql在使用不同索引的时候,得到的数据顺序是不一样的。这个可能就跟Mysql的索引建立机制,以及索引的使用有关了。更深的东西,在这里就不深追了。为了避免这种情况,在以后的项目中,切记要加上order by
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。