【今日推荐】:为什么一到面试就懵逼!>>>
- 目录
- 1. 前言
- 2. 重演案例
- 2.1 mysql数据表结构
- 2.2 问题排查
- 2.2.1出问题的SQL查询
- 2.2.2优化后的SQL查询
- 3. 探讨分析和总结
1. 前言
前几天公司某项目读取的全部数据条数是13条,分页limit是10,但是显示出来的数据却只有11条,也就是说丢失了两条数据,那这是什么原因导致的呢?刚开始,这个问题让我百思不解,后来上百度求解答的时候,看到了一个和我遇到类似问题的博主发的一篇文章,顿时心花路放,感觉自己经验不够,为了防止忘记,在这里记录一下下.
首先给出参考博文地址,以示尊重:
https://blog.csdn.net/tsxw24/article/details/44994835
2. 重演案例
2.1 mysql数据表结构
CREATE TABLE `NewTable` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门id' ,
`partnerid` int(11) NOT NULL COMMENT '线下合作商ID' ,
`department_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '部门名称' ,
`addremark` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '无备注' COMMENT '添加部门备注' ,
`del` tinyint(1) NOT NULL DEFAULT 1 COMMENT '关闭部门 默认1 关闭2' ,
`delremark` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '无备注' COMMENT '关闭部门备注' ,
`sort_num` int(11) NOT NULL DEFAULT 0 COMMENT '排序 数字越大越靠前' ,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8mb4 COLLATE=utf8mb4_general_ci
COMMENT='线下合作-部门(子公司)'
AUTO_INCREMENT=1
ROW_FORMAT=COMPACT
;
2.2 问题排查
2.2.1出问题的SQL查询
$sql = "
SELECT
p1.`id`,p1.`department_name`,p1.`del` AS delStatus,p1.sort_num
FROM
`t_partner_department` AS p1
WHERE {$where}
ORDER BY p1.`sort_num` DESC
LIMIT {$limits}
";
可以看到上面的SQL语句是根据字段sort_num来排序的,但我们添加部门信息的时候是不会设置排序值的,默认为0,所以当使用上述SQL语句查询,由于SQL排序值大多为0,而在排序相等的情况下,oeder by排序的顺序是随机的,而不是固定的,于是出现了数据丢失问题。
2.2.2优化后的SQL查询
$sql = "
SELECT
p1.`id`,p1.`department_name`,p1.`del` AS delStatus,p1.sort_num
FROM `t_partner_department` AS p1
WHERE {$where}
ORDER BY p1.`sort_num` DESC ,p1.`id` ASC
LIMIT {$limits}";
可以看到上面SQL语句的oeder by排序除了根据sort_num降序,还根据id进行升序,如果sort_num排序值相同,那么则以id排序值为准;反之,如果sort_num排序值不同,则先按照sort_num排序,然后再把sort_num排序值相同的按照id排序。
3. 探讨分析和总结
通过排查,如果SQL查询不使用了order by和limit,输出的数据是完整的,但是一旦使用它们来做数据分页显示并排序,如果order by的排序值大多相等,则会造成顺序的不确定,因为在排序值相同的情况下,order by排序的顺序是随机的而不是固定的;因此,我们可以通过增加排序条件让其排序结果是确定的、唯一的,这样就能够使得排序固定,而不出现数据丢失的问题。