SQL默认排序遇到的坑

博客讲述了在MySQL中,由于新增索引导致默认排序发生变化,从而在分页查询时出现数据遗漏的问题。作者通过分析表结构和查询语句,发现查询开始使用uid排序而非预期的id排序。为解决此问题,提出了两种解决方案:强制索引和指定排序字段,并进行了性能对比,建议在实际场景中根据数据量选择合适的方法。
摘要由CSDN通过智能技术生成

默认排序遇到的坑

问题描述

根据id分页查询,每次1000条,默认排序方式(主键)。

在未知情况下,表被加了索引,sql命中新索引,排序方式改变,导致根据id分页查询,数据有遗漏。

问题重现

表结构

SHOW CREATE TABLE com.account_day_snapshot;

CREATE TABLE `account_day_snapshot` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `day` date NOT NULL COMMENT '每日余额日期',
  `uid` int(11) NOT NULL DEFAULT '0',
  `type` int(11) NOT NULL DEFAULT '0',
  `balance` decimal(32,16) NOT NULL DEFAULT '0.0000000000000000' COMMENT '余额',
  PRIMARY KEY (`id`),
  KEY `idx_day` (`day`)
) ENGINE=InnoDB AUTO_INCREMENT=506499565 DEFAULT CHARSET=utf8 COMMENT='账户每日余额快照'

查询数据

数据默认使用id排序

SELECT * from com.account_day_snapshot
 WHERE id >=0 and day = '2021-04-28' 
 and type = '2011002';

在这里插入图片描述

添加索引

添加唯一索引:day_type_uid索引

show index from com.account_day_snapshot;
show index from com.account_day_snapshot_copy1;

在这里插入图片描述
在这里插入图片描述

查询数据

数据命中udx_day_type_uid索引,使用uid排序

 SELECT * from com.account_day_snapshot_copy1
 WHERE id >=0 and day = '2021-04-28' 
 and type = '2011002';

在这里插入图片描述

SQL分析

EXPLAIN
SELECT * from com.account_day_snapshot
 WHERE id >=0 and day = '2021-04-28' 
 and type = '2011002';

-- 加了新索引
 EXPLAIN
 SELECT * from com.account_day_snapshot_copy1
 WHERE id >=0 and day = '2021-04-28' 
 and type = '2011002';

在这里插入图片描述
在这里插入图片描述

由此可以看出,未加新索引之前,查询命中idx_day索引,使用id排序;加新索引之前,查询命中udx_day_type_uid索引,使用uid排序,id不是有序的。因此使用id作为条件分页查询时,数据会有遗漏。

问题解决

  • 使用强制索引

    SELECT  * from com.account_day_snapshot_copy1 force index( idx_day )
     WHERE id >=0 and day = '2021-04-28' 
     and type = '2011002';
    
  • 指定排序字段

     SELECT  * from com.account_day_snapshot_copy1
     WHERE id >=0 and day = '2021-04-28' 
     and type = '2011002' ORDER BY id;
    

性能对比

 EXPLAIN
   SELECT  * from com.account_day_snapshot_copy1 force index( idx_day )
 WHERE id >=0 and day = '2021-04-28' 
 and type = '2011002';
 
  EXPLAIN
   SELECT  * from com.account_day_snapshot_copy1
 WHERE id >=0 and day = '2021-04-28' 
 and type = '2011002' ORDER BY id;

在这里插入图片描述
在这里插入图片描述

这里采用指定排序字段更优,当然具体情况需要根据线上实际数据量判断。

更多MySQL问题可以参考:
想知道大厂核心业务系统数据储存方法? 懂分布式架构设计就够了!

极数云周CEO-周彦伟,带你掌握MySQL的底层运行机制,会学如何处理海量业务数据和高并发请求。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

future_1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值