If multiple rows have identical values in the ORDER BY columns, the server is free to return those rows in any order, and may do so differently depending on the overall execution plan. In other words, the sort order of those rows is nondeterministic with respect to the nonordered columns.
One factor that affects the execution plan is LIMIT, so an ORDER BY query with and without LIMIT may return rows in different orders.
问题重现
本次实验使用社区版 MySQL 5.6.26(因为小明出现问题的环境就是这个版本O(∩_∩)O~),下面先创建实验环境和初始化测试数据:
root@localhost [(none)]>select @@version;
1 row in set (0.00 sec)
root@localhost [(none)]>show variables like "sql_mode";
| Variable_name | Value |
| sql_mode | NO_ENGINE_SUBSTITUTION |
1 row in set (0.00 sec)
root@localhost [(none)]>create database glon_ho;
Query OK, 1 row affected (0.04 sec)
root@localhost [(none)]>use glon_ho
Database changed
root@localhost [glon_ho]>create table glon(
-> id int not null auto_increment primary key,
-> name varchar(20) not null,
-> create_time datetime not null,
-> age tinyint unsigned default 18
-> );
Query OK, 0 rows affected (0.01 sec)
root@localhost [glon_ho]>INSERT INTO `glon` VALUES (1, 'Eason Chan', '2017-05-02 08:10:10', 19),(2, 'Glon Ho', '2017-05-03 12:10:10', 18),(3, '赵敏', '2017-05-03 14:10:10', 17),(4, 'Jacky Cheung', '2017-05-02 14:00:00', 22),(5, '周芷若', '2017-05-02 14:00:00', 16),(6, 'Andy Lau', '2017-05-02 14:00:00', 50),(7, '至尊宝', '2017-05-02 14:00:00', 20),(8, '刘三姐', '2017-05-02 14:00:00', 19);
Query OK, 8 rows affected (0.01 sec)
Records: 8 Duplicates: 0 Warnings: 0
root@localhost [glon_ho]>select * from glon;
| id | name | create_time | age |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
8 rows in set (0.00 sec)
这里创建了一个 glon 表,字段有自增 id, 姓名 name, 年龄 age, 及用户注册时间 create_time。
接着来复现问题:
根据用户注册时间 create_time 来排序:
root@localhost [glon_ho]>select * from glon ORDER BY create_time limit 0, 4;
| id | name | create_time | age |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time limit 4, 4;
| id | name | create_time | age |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
4 rows in set (0.00 sec)
可以看到两次查询结果中都出现了 id 为8的刘三姐,从上面初始化数据来看,总共有 8 条数据,现在不但分页出现重复数据,还丢了一条!
问题确实重现了,不过先不急,我们再来试多几组其他的排序方式。
create_time 和age 组合排序
root@localhost [glon_ho]>select * from glon ORDER BY create_time,age limit 0, 4;
| id | name | create_time | age |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time,age limit 4, 4;
| id | name | create_time | age |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
4 rows in set (0.00 sec)
create_time 和id 组合排序
root@localhost [glon_ho]>select * from glon ORDER BY create_time,id limit 0, 4;
| id | name | create_time | age |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time,id limit 4, 4;
| id | name | create_time | age |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
4 rows in set (0.00 sec)
主键 id 排序
root@localhost [glon_ho]>select * from glon ORDER BY id limit 0, 4;
| id | name | create_time | age |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY id limit 4, 4;
| id | name | create_time | age |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
4 rows in set (0.00 sec)
看到,后面的几组排序方式都没有再出现问题了,结合官档,我们知道 order by 排序的时候,如果排序字段中有多行相同的列值,则排序结果是不确定的。所以后面的几组组合形式的排序或者是主键 id 的排序,因为唯一性高,所以排序是确定的,不会出现结果混乱的问题。
那是不是可以就此结束了呢,no way, 我们再来看下面的实验,继续巩固一下:
根据年龄 age 来排序:
root@localhost [glon_ho]>select * from glon ORDER BY age limit 0, 4;
| id | name | create_time | age |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY age limit 4, 4;
| id | name | create_time | age |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
4 rows in set (0.00 sec)
咦,这个排序也只是根据一个字段 age 来排序,怎么就没有出问题呢?不急,还有招:
root@localhost [glon_ho]>insert into glon values (9,'乔峰','2017-05-03 13:10:10',22),(10,'段誉','2017-05-03 15:10:10',19),(11,'郭靖','2017-05-03 17:10:10',20),(12,'黄蓉','2017-05-03 08:10:10',19);
Query OK, 4 rows affected (0.01 sec)
Records: 4 Duplicates: 0 Warnings: 0
root@localhost [glon_ho]>select * from glon;
| id | name | create_time | age |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 9 | 乔峰 | 2017-05-03 13:10:10 | 22 |
| 10 | 段誉 | 2017-05-03 15:10:10 | 19 |
| 11 | 郭靖 | 2017-05-03 17:10:10 | 20 |
| 12 | 黄蓉 | 2017-05-03 08:10:10 | 19 |
12 rows in set (0.00 sec)
我又给 glon 表新增了几条数据,然后再来看看:
root@localhost [glon_ho]>select * from glon ORDER BY create_time limit 0, 4;
| id | name | create_time | age |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time limit 4, 4;
| id | name | create_time | age |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 12 | 黄蓉 | 2017-05-03 08:10:10 | 19 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time limit 8, 4;
| id | name | create_time | age |
| 9 | 乔峰 | 2017-05-03 13:10:10 | 22 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 10 | 段誉 | 2017-05-03 15:10:10 | 19 |
| 11 | 郭靖 | 2017-05-03 17:10:10 | 20 |
4 rows in set (0.00 sec)
根据 create_time 排序,没有问题了,再来:
root@localhost [glon_ho]>select * from glon ORDER BY age limit 0, 4;
| id | name | create_time | age |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY age limit 4, 4;
| id | name | create_time | age |
| 12 | 黄蓉 | 2017-05-03 08:10:10 | 19 |
| 10 | 段誉 | 2017-05-03 15:10:10 | 19 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY age limit 8, 4;
| id | name | create_time | age |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 9 | 乔峰 | 2017-05-03 13:10:10 | 22 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
4 rows in set (0.00 sec)
可以看到根据年龄 age 排序,问题出现了。
然后在看看组合的排序:
root@localhost [glon_ho]>select * from glon ORDER BY create_time,id limit 0, 4;
| id | name | create_time | age |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time,id limit 4, 4;
| id | name | create_time | age |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 12 | 黄蓉 | 2017-05-03 08:10:10 | 19 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time,id limit 8, 4;
| id | name | create_time | age |
| 9 | 乔峰 | 2017-05-03 13:10:10 | 22 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 10 | 段誉 | 2017-05-03 15:10:10 | 19 |
| 11 | 郭靖 | 2017-05-03 17:10:10 | 20 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time,age limit 0, 4;
| id | name | create_time | age |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time,age limit 4, 4;
| id | name | create_time | age |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
| 12 | 黄蓉 | 2017-05-03 08:10:10 | 19 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY create_time,age limit 8, 4;
| id | name | create_time | age |
| 9 | 乔峰 | 2017-05-03 13:10:10 | 22 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 10 | 段誉 | 2017-05-03 15:10:10 | 19 |
| 11 | 郭靖 | 2017-05-03 17:10:10 | 20 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY age,id limit 0, 4;
| id | name | create_time | age |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY age,id limit 4, 4;
| id | name | create_time | age |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 10 | 段誉 | 2017-05-03 15:10:10 | 19 |
| 12 | 黄蓉 | 2017-05-03 08:10:10 | 19 |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon ORDER BY age,id limit 8, 4;
| id | name | create_time | age |
| 11 | 郭靖 | 2017-05-03 17:10:10 | 20 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 9 | 乔峰 | 2017-05-03 13:10:10 | 22 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
4 rows in set (0.00 sec)
思考
既然排序不定,那么给排序字段加上索引会不会有用呢?
root@localhost [glon_ho]>alter table glon add index ix_age(age);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
root@localhost [glon_ho]>show create table glon\G
*************************** 1. row ***************************
Table: glon
Create Table: CREATE TABLE `glon` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
`create_time` datetime NOT NULL,
`age` tinyint(3) unsigned DEFAULT '18',
PRIMARY KEY (`id`),
KEY `ix_age` (`age`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
root@localhost [glon_ho]>select * from glon order by age limit 0,4;
| id | name | create_time | age |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon order by age limit 4,4;
| id | name | create_time | age |
| 12 | 黄蓉 | 2017-05-03 08:10:10 | 19 |
| 10 | 段誉 | 2017-05-03 15:10:10 | 19 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from glon order by age limit 8,4;
| id | name | create_time | age |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 9 | 乔峰 | 2017-05-03 13:10:10 | 22 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
4 rows in set (0.00 sec)
也可以不在 order by 后面加多一列增加唯一性,可以改写成下面的形式:
root@localhost [glon_ho]>select * from (select distinct g.* from glon g order by age) t limit 0,4;
| id | name | create_time | age |
| 5 | 周芷若 | 2017-05-02 14:00:00 | 16 |
| 3 | 赵敏 | 2017-05-03 14:10:10 | 17 |
| 2 | Glon Ho | 2017-05-03 12:10:10 | 18 |
| 1 | Eason Chan | 2017-05-02 08:10:10 | 19 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from (select distinct g.* from glon g order by age) t limit 4,4;
| id | name | create_time | age |
| 10 | 段誉 | 2017-05-03 15:10:10 | 19 |
| 8 | 刘三姐 | 2017-05-02 14:00:00 | 19 |
| 12 | 黄蓉 | 2017-05-03 08:10:10 | 19 |
| 11 | 郭靖 | 2017-05-03 17:10:10 | 20 |
4 rows in set (0.00 sec)
root@localhost [glon_ho]>select * from (select distinct g.* from glon g order by age) t limit 8,4;
| id | name | create_time | age |
| 7 | 至尊宝 | 2017-05-02 14:00:00 | 20 |
| 9 | 乔峰 | 2017-05-03 13:10:10 | 22 |
| 4 | Jacky Cheung | 2017-05-02 14:00:00 | 22 |
| 6 | Andy Lau | 2017-05-02 14:00:00 | 50 |
4 rows in set (0.00 sec)
总之,如果发生了,最简单的方法就是在排序列(如create time)上加索引,然后在 order by 上明示 primary key,这个问题就非常圆满的解决了。
总结
MySQL 使用 limit 进行分页时,可能会出现重复数据,通过加入 order by 子句可以解决,但是需要注意的是,如果排序字段有相同值的情况下,由于排序字段数据重复,可能会导致每次查询排序后结果顺序不同,分页还是会出现重复数据,这时可以加入第二个排序字段,提高排序的唯一性,最好保证排序的字段在表中的值是唯一的,这样就可以少写一个排序字段,增加查询效率,因为 order by 后面有多个排序字段时,无法用到索引。
推荐 2015年06 月《数据库内核月报》的一篇旧文:MySQL · 答疑解惑 · MySQL Sort 分页
使用mysql时的坑mysql分页数据重复mysql分页数据重复 最近线上反馈一个问题,某个列表接口,第二页的返回的数据里面有条数据和第一页的重复了。然后我去调了接口,确实会重现,并且一页10条和一页20条数据,接口...

使用mysql时的坑

mysql分页数据重复
最近线上反馈一个问题,某个列表接口,第二页的返回的数据里面有条数据和第一页的重复了。然后我去调了接口,确实会重现,并且一页10条和一页20条数据,接口返回的数据顺序不一样。
初看sql,又觉得没有问题。
select	uuid, 。。。	from	attendance_month_list	where	project_uuid in	。。。	and del_flag=0 order by year desc,month desc
然后,我试了下把排序去掉, 就不会有重复的问题,就确定到是排序有问题。
后面发现是只根据年月排序的话,如果相同年月的数据有10多条,分页10条的时候,就会出现上面的问题。
解决办法:
select	uuid, 。。。	from	attendance_month_list	where	project_uuid in	。。。	and del_flag=0 order by year desc,month desc,**uuid**
结论:排序的时候,要确保排序条件一定有最终优先级
0 问题描述在MySQL中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页。但是,当limit遇到order by的时候,可能会出现翻到第二页的时候,竟然又出现了第一...
0 问题描述
在MySQL中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页。但是,当limit遇到order by的时候,可能会出现翻到第二页的时候,竟然又出现了第一页的记录。
具体如下:
SELECT
`post_title`,
`post_date`
FROM
post
WHERE
`post_status`=
'publish'
ORDER
BY
view_count
desc
LIMIT
使用上述SQL查询的时候,很有可能出现和LIMIT 0,5相同的某条记录。而如果使用如下方式,则不会出现重复的情况:
SELECT
FROM
post
WHERE
post_status=
'publish'
ORDER
BY
view_count
desc
LIMIT
但是,由于post表的字段很多,仅仅希望用这两个字段,不想把post_content也查出来。为了解决这个情况,在ORDER BY后面使用了两个排序条件来解决这个问题,如下:
SELECT
`post_title`,
`post_date`
FROM
post
WHERE
`post_status`=
'publish'
ORDER
BY
view_count
desc,
ID
asc
LIMIT
按理来说,MySQL的排序默认情况下是以主键ID作为排序条件的,也就是说,如果在view_count相等的情况下,主键ID作为默认的排序条件,不需要我们多此一举加ID asc。
但是事实就是,MySQL再order by和limit混用的时候,出现了排序的混乱情况。
1 分析问题
在MySQL 5.6的版本上,优化器在遇到order by limit语句的时候,做了一个优化,即 使用了priority queue。
使用 priority queue 的目的,
就是在不能使用索引有序性的时候,如果要排序,并且使用了limit n,那么只需要在排序的过程中,保留n条记录即可,这样虽然不能解决所有记录都需要排序的开销,但是
只需要 sort buffer 少量的内存就可以完成排序。
之所以MySQL 5.6出现了第二页数据重复的问题,
是因为 priority queue 使用了堆排序的排序方法,而堆排序是一个不稳定的排序方法,也就是相同的值可能排序出来的结果和读出来的数据顺序不一致。
MySQL 5.5 没有这个优化,所以也就不会出现这个问题。
也就是说,MySQL 5.5是不存在本文提到的问题的,5.6版本之后才出现了这种情况。
再看下MySQL解释sql语言时的执行顺序:
SELECT
DISTINCT
FROM
JOIN
ON
WHERE
GROUP
BY
HAVING
ORDER
BY
LIMIT
执行顺序依次为 form… where… select… order by… limit…,由于上述priority queue的原因,在完成select之后,所有记录是以堆排序的方法排列的,在进行order by时,仅把view_count值大的往前移动。
但由于limit的因素,排序过程中只需要保留到5条记录即可,view_count并不具备索引有序性,所以当第二页数据要展示时,mysql见到哪一条就拿哪一条,因此,当排序值相同的时候,第一次排序是随意排的,第二次再执行该sql的时候,其结果应该和第一次结果一样。
查看全文请点击文章顶部链接
问题:分页显示,有些数据会重复出现在不同的页面里面 分析: sql语句类似于: select id, name , ...开发时使用navicat测试,看不出来不同页面有重复数据,但是如果把navicat关掉,重新打开再查询一次,就会发...
问题: 分页显示,有些数据会重复出现在不同的页面里面
分析: sql语句类似于: select id, name , grade form score order by grade desc limit 10 offset 0
由于有相同成绩没有考虑到,相同成绩的同学之间排序是乱序。
开发时使用navicat测试,看不出来不同页面有重复数据,但是如果把navicat关掉,重新打开再查询一次,就会发现相同成绩的同学之间排序和上次不一样。(如果相同成绩的同学个数足够多的话会更明显)
前端调用接口时,效果类似于把navicat打开再关掉。所以导致了不同页面显示有重复的数据
修改:相同成绩使用id排序,增加一个id排序
select id, name , grade form score order by grade desc,idlimit 10 offset 0
解决方案 order by 或者使用groupby 转载于:https://www.cnblogs.com/zfzf1/p/10971777.html
今天写了一个分页的功能,我用了创建时间createdTime进行排序,结果查出来的数据相邻的两页有重复,而且还丢失了一个数据。但是不分页查询的时候没有问题,后来发现有几个数据创建时间createdTime是一样的,这里主要...
0 问题描述在MySQL中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页。但是,当limit遇到order by的时候,可能会出现翻到第二页的时候,竟然又出现了第一...
解决MySQL分页数据错乱重复前言一天,小明很着急地在通讯工具上说:这边线上出现了个奇怪的问题,麻烦 DBA 大大鉴定下,执行语句select xx from table_name wheere xxx order by 字段A limit offset;,表数据...
Oracle分页查询:Oracle的分页查询是没有进行任何排序操作的,Oracle是...造成分页查询数据重复出现的原因是:在数据中,排序列值的不唯一性解决方法如下(两个条件必须同时满足):1.sql语句中需要有排序条件。2.排...
表数据总共 48 条,分页数量正常,但出现了结果混杂的情况,第一页的数据出现在了第二页上;如果 order by 字段B 就不会出现这个现象,怎么会这样呢! If multiple rows have identical values in the ORDER ...
今天正在搬砖的时候运营报过来一个问题,查询用户角色列表数据丢失了,通过查询发现是因为分页导致的第一页和第二页有重复数据 像上面这两张图一样,去扒代码中的sql发现sql语句用了order by update_time 做...
问题描述在MySQL中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页。但是,当limit遇到order by的时候,可能会出现翻到第二页的时候,竟然又出现了第一页...
作者丨猿码道https://www.jianshu.com/p/544c319fd838问题描述在MySQL中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页。但是,当limit遇到o...
昨天项目测试报了个bug,分页列表中,第一页的数据,在第二页也存在,同时也丢失了一条数据。 于是我就上网开始扒拉扒拉。。。。昨天下午年会,于是今天周六加班搞! 原来是Sql 的问题。 原映射文件的sql语句...
mysql分页查询出现重复数据问题排查mysql分页查询出现重复数据问题分析定位问题解决方案mysql分页查询出现重复数据 2019的最后一天,才发现今年快过去了,就想着写点东西纪念一下,而且正好昨天项目上遇见一个让...
项目用了mysql5.6 版(5.6.39),查询某个表时根据时间排序,用limit分页时发现当前页的某项数据在下一页偶尔也会出现,导致我们认为本该出现的数据没有出现(即所谓“丢失”)。并且每次limit不同的页导致有部分...
线上遇到一个问题,使用mysql分页获取数据会获取到重复的数据,比如一共一万条数据,分页取出来之后合并到一起会有重复的几条,而且每次重复的数据都不太一样,但是直接全量获取就没有问题,数据库建表语句如下:...
0 问题描述在MySQL中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页。但是,当limit遇到order by的时候,可能会出现翻到第二页的时候,竟然又出现了第一...
mysql分页加排序数据重复问题解决方案
其实今天遇到的最大问题还是mysql order by limit 排序分页数据重复的问题,昨天晚上搞了3个小时都没处理,因为不管怎么查数据也总会重复,查询了好多,都反映说在 order by上加一个主键UUID唯一的排序,然后再分页...
最近在使用mysql分页查询数据的时候发现返回的数据与预期的不一样,显示数据重复错乱。 在官方文档有这样一句话 If multiple rows have identical values in theORDER BYcolumns, the server is free to return...
0 问题描述在MySQL中我们通常会采用limit来进行翻页查询,比如limit(0,10)表示列出第一页的10条数据,limit(10,10)表示列出第二页。但是,当limit遇到order by的时候,可能会出现翻到第二页的时候,竟然又出现了第一...
用户找到我说系统出现了重复的数据,起初还以为是录多了,后来发现是sql写错了…不仅有重复,还会有丢失不显示的。 就像上面两张图,一样的数据查找,为什么会显示不一样。后来经过排除,发现问题出在了order by...