前言

一天,小明很着急地在通讯工具上说:这边线上出现了个奇怪的问题,麻烦 DBA 大大鉴定下,执行语句 select xx from table_name wheere xxx order by 字段A limit offset;

表数据总共 48 条,分页数量正常,但出现了结果混杂的情况,第一页的数据出现在了第二页上;如果 order by 字段B 就不会出现这个现象,怎么会这样呢!

其实,这个问题很简单,如果你有仔细阅读官档的话。^_^

我们先来看看官档是怎么说的:

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;
+------------+
| @@version |
+------------+
| 5.6.26-log |
+------------+
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 分页数据错乱重复的更多相关文章

  1. MySQL 分页数据错乱重复

    select xx from table_name wheere xxx order by 字段A limit offset;, 表数据总共 48 条,分页数量正常,但出现了结果混杂的情况,第一页的数 ...

  2. mysql 分页数据错乱

    最近在使用mysql 分页查询数据的时候发现返回的数据与预期的不一样,显示数据重复错乱. 在官方文档 有这样一句话 If multiple rows have identical values in ...

  3. EF获取多个数据集以及MySQL分页数据查询优化

    背景:MySQL分页查询语句为 ,10; 一般页面还会获取总条数,这时候还需要一条查询总条数语句 , 这样数据库需要执行两次查询操作.MySQL提供了SQL_CALC_FOUND_ROWS追踪总条数的 ...

  4. Mysql 删除数据表重复行

    准备示例数据 以下sql创建表,并将示例数据插入到用于演示的contacts表中. CREATE TABLE contacts ( id INT PRIMARY KEY AUTO_INCREMENT, ...

  5. php 解决MySQL插入数据出现 Incorrect string value: '\xF0\x9F\x92\x8BTi...'错误

    在项目中向MySQL插入数据时.发现数据插入不完整,通过调试,发现插入语句也没什么特殊的错误. 可是就是差不进去,于是就打开mysqli错误的调试 $ret = mysqli_query($this- ...

  6. SpringMVC+Mybatis实现的Mysql分页数据查询

    周末这天手痒,正好没事干,想着写一个分页的例子出来给大家分享一下. 这个案例分前端和后台两部分,前端使用面向对象的方式写的,里面用到了一些回调函数和事件代理,有兴趣的朋友可以研究一下.后台的实现技术是 ...

  7. 解决mysql插入数据时出现Incorrect string value: '\xF0\x9F...' for column 'name' at row 1的异常

    这个问题,原因是UTF-8编码有可能是两个.三个.四个字节.Emoji表情或者某些特殊字符是4个字节,而MySQL的utf8编码最多3个字节,所以数据插不进去. 我的解决方案是这样的 1.在mysql ...

  8. 解决mysql导入数据量很大导致失败及查找my.ini 位置(my.ini)在哪

    数据库数据量很大的数据库导入到本地时,会等很久,然而等很久之后还是显示失败: 这是就要看看自己本地的没mysql是否设置了超时等待,如果报相关time_out这些,可以把mysql.ini尾部添加ma ...

  9. 解决mysql插入数据l出现"the table is full"的问题

    需要修改Mysql的配置文件my.ini,在[mysqld]下添加/修改两行:tmp_table_size = 256Mmax_heap_table_size = 256M

随机推荐

  1. django generic view - ListView

    ListView (带分页) 1.带分页效果的基础模板 1) view from django.views.generic.list import ListView from employ.model ...

  2. 我的Node.js学习历程

    学习一门技术,每个人都有每个人的方法.我的方法很简单,做项目. 基本概念 在搭建一个node网站之前,还是要掌握一些基本的概念的,这里列举一下,具体的内容大家自己到网上去查: npm bower ex ...

  3. windows phone 8.1开发:磁铁|Tile更新

    原文出自:http://www.bcmeng.com/tile/ 上一篇给大家分享了toast通知操作的方法,这一篇文章我们就来看windows phone 8.1开发中的磁铁更新.磁铁是window ...

  4. Java开发过程中开发工具Eclipse中导入jar包的过程

    欢迎欣赏我的第二篇随笔.我们在创建好一个动态网站项目之后,如果没有部署maven的情况下,你可以按照以下的方法,直接把要用的jar包导入你的工程中,而不用再部署maven. 例如在使用JDBC编程时需 ...

  5. Openstack新建云主机的流程

    前言 前天晚上没睡觉,所以昨天睡得很早,导致今天4点就起来了 时间是人最宝贵的财富,于是我打消了钻在被子里刷剧的念头,爬起来整理一下在Openstack中新建一个云主机的流程. Openstack可以 ...

  6. Apache Mina入门实例

    一.mina是啥 ApacheMINA是一个网络应用程序框架,用来帮助用户简单地开发高性能和高可扩展性的网络应用程序.它提供了一个通过Java NIO在不同的传输例如TCP/IP和UDP/IP上抽象的 ...

  7. 性能调优案例分享:jvm crash的原因 1

    性能调优案例分享:jvm crash的原因   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq: ...

  8. 测试开发Python培训:模拟登录新浪微博-技术篇

    测试开发Python培训:模拟登录新浪微博-技术篇   一般一个初学者项目的起点就是登陆功能的自动化,而面临的项目不同实现的技术难度是不一样的,poptest在做测试开发培训中更加关注技术难点,掌握技 ...

  9. input是否checked与使用jquery的attr或prop方法无关

    最近在项目中有这样一个需求,用户在下单时可以选择优惠券,也可取消选择,并且可以多次选择,取消. 这是一个典型的input标签checked功能,博主使用radio元素实现此需求,但是优惠券只能选中,不 ...

  10. 常用linux命令及其设置

    完成一个运维的工作,以下的命令和配置是经常会用到的,总结一下工作以来的命令和配置 linux常用命令 linux客户端挂接(mount)其他linux系统或UNIX系统的NFS共享 $ mkdir – ...