RDS MySQL排序分页查询数据顺序错乱的处理

免责声明:本文档可能包含第三方产品信息,该信息仅供参考。阿里云对第三方产品的性能、可靠性以及操作可能带来的潜在影响,不做任何暗示或其他形式的承诺。

问题描述

MySQL排序分页查询某些时候会出现数据顺序错乱的情况,例如alarm_test表结构如下所示。

CREATE TABLE alarm_test (
  id bigint(20) NOT NULL DEFAULT '0',
  detail varchar(255) CHARACTER SET utf8 NOT NULL,
  created_on timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

按照created_on字段值排序,取前10行,如下图。

created_on前10

按照created_on字段值排序,取从11行开始的10行,如下图,可以看出2次排序分页操作得到的数据是有重合而且无序的。

created_on11

问题原因

排序分页结果会根据情况的不同而变化,结果不可预料。且created_on字段的值在前21行记录中有20行数据相同。

解决方案

阿里云提醒您:

  • 如果您对实例或数据有修改、变更等风险操作,务必注意实例的容灾、容错能力,确保数据安全。
  • 如果您对实例(包括但不限于ECS、RDS)等进行配置与数据修改,建议提前创建快照或开启RDS日志备份等功能。
  • 如果您在阿里云平台授权或者提交过登录账号、密码等安全信息,建议您及时修改。

使排序字段有序的排序有如下两种方法。

  • 修改排序规则,加入主键字段,使排序字段不存在重复记录,SQL语句如下所示。
    select id, created_on from alarm_test order by created_on, id limit 0,10;
    select id, created_on from alarm_test order by created_on, id limit 10,10;
    系统显示类似如下。
    加入主键字段
  • 在出现重复值的排序字段上添加索引,如下所示。
    CREATE TABLE alarm_test_idx (
    id bigint(20) NOT NULL DEFAULT '0',
    detail varchar(255) CHARACTER SET utf8 NOT NULL,
    created_on timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    KEY created_on (created_on)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    说明:推荐使用添加索引的方法,在提供可预期的结果同时,提高查询的执行效率,如下图所示。添加索引

适用于

  • 云数据库RDS MySQL版