如何解决MySQL order by limit语句的分页数据重复问题?
阅读本文大概需要 3.5 分钟。
来自:https://www.jianshu.com/p/544c319fd838
0 问题描述
SELECT `post_title`,`post_date` FROM post WHERE `post_status`='publish' ORDER BY view_count desc LIMIT 5,5
SELECT * FROM post WHERE post_status='publish' ORDER BY view_count desc LIMIT 5,5
SELECT `post_title`,`post_date` FROM post WHERE `post_status`='publish' ORDER BY view_count desc,ID asc LIMIT 5,5
1 分析问题
MySQL 5.5 没有这个优化,所以也就不会出现这个问题。
(1) SELECT
(2) DISTINCT <select_list>
(3) FROM <left_table>
(4) <join_type> JOIN <right_table>
(5) ON <join_condition>
(6) WHERE <where_condition>
(7) GROUP BY <group_by_list>
(8) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <limit_number>
2 解决方法
如果在字段添加上索引,就直接按照索引的有序性进行读取并分页,从而可以规避遇到的这个问题。
分页是建立在排序的基础上,进行了数量范围分割。排序是数据库提供的功能,而分页却是衍生的出来的应用需求。 在MySQL和Oracle的官方文档中提供了limit n和rownum < n的方法,但却没有明确的定义分页这个概念。 还有重要的一点,虽然上面的解决方法可以缓解用户的这个问题,但按照用户的理解,依然还有问题 比如,这个表插入比较频繁,用户查询的时候,在read-committed的隔离级别下,第一页和第二页仍然会有重合。 所以,分页一直都有这个问题,不同场景对数据分页都没有非常高的准确性要求。
用户在使用Oracle或MySQL的时候,发现MySQL总是有序的,Oracle却很混乱,这个主要是因为Oracle是堆表,MySQL是索引聚簇表的原因。 所以没有order by的时候,数据库并不保证记录返回的顺序性,并且不保证每次返回都一致的。
如前面所描述的,分页是在数据库提供的排序功能的基础上,衍生出来的应用需求,数据库并不保证分页的重复问题。
不同的数据库对于NULL值和空串的理解和处理是不一样的 比如Oracle NULL和NULL值是无法比较的,既不是相等也不是不相等,是未知的。 而对于空串,在插入的时候,MySQL是一个字符串长度为0的空串,而Oracle则直接进行NULL值处理。
扫码加入技术交流群,不定时「送书」
推荐阅读:
处理 Exception 的几种实践,很优雅,被很多团队采纳!
吊炸天的 Docker 图形化工具:Portainer,必须推荐给你!
最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
朕已阅
评论