如何解決MySQL order by limit語(yǔ)句的分頁(yè)數(shù)據(jù)重復(fù)問(wèn)題?
閱讀本文大概需要 3.5 分鐘。
來(lái)自:https://www.jianshu.com/p/544c319fd838
0 問(wèn)題描述
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 分析問(wèn)題
MySQL 5.5 沒(méi)有這個(gè)優(yōu)化,所以也就不會(huì)出現(xiàn)這個(gè)問(wèn)題。
(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 解決方法
如果在字段添加上索引,就直接按照索引的有序性進(jìn)行讀取并分頁(yè),從而可以規(guī)避遇到的這個(gè)問(wèn)題。
分頁(yè)是建立在排序的基礎(chǔ)上,進(jìn)行了數(shù)量范圍分割。排序是數(shù)據(jù)庫(kù)提供的功能,而分頁(yè)卻是衍生的出來(lái)的應(yīng)用需求。 在MySQL和Oracle的官方文檔中提供了limit n和rownum < n的方法,但卻沒(méi)有明確的定義分頁(yè)這個(gè)概念。 還有重要的一點(diǎn),雖然上面的解決方法可以緩解用戶的這個(gè)問(wèn)題,但按照用戶的理解,依然還有問(wèn)題 比如,這個(gè)表插入比較頻繁,用戶查詢的時(shí)候,在read-committed的隔離級(jí)別下,第一頁(yè)和第二頁(yè)仍然會(huì)有重合。 所以,分頁(yè)一直都有這個(gè)問(wèn)題,不同場(chǎng)景對(duì)數(shù)據(jù)分頁(yè)都沒(méi)有非常高的準(zhǔn)確性要求。
用戶在使用Oracle或MySQL的時(shí)候,發(fā)現(xiàn)MySQL總是有序的,Oracle卻很混亂,這個(gè)主要是因?yàn)镺racle是堆表,MySQL是索引聚簇表的原因。 所以沒(méi)有order by的時(shí)候,數(shù)據(jù)庫(kù)并不保證記錄返回的順序性,并且不保證每次返回都一致的。
如前面所描述的,分頁(yè)是在數(shù)據(jù)庫(kù)提供的排序功能的基礎(chǔ)上,衍生出來(lái)的應(yīng)用需求,數(shù)據(jù)庫(kù)并不保證分頁(yè)的重復(fù)問(wèn)題。
不同的數(shù)據(jù)庫(kù)對(duì)于NULL值和空串的理解和處理是不一樣的 比如Oracle NULL和NULL值是無(wú)法比較的,既不是相等也不是不相等,是未知的。 而對(duì)于空串,在插入的時(shí)候,MySQL是一個(gè)字符串長(zhǎng)度為0的空串,而Oracle則直接進(jìn)行NULL值處理。
掃碼加入技術(shù)交流群,不定時(shí)「送書(shū)」
推薦閱讀:
處理 Exception 的幾種實(shí)踐,很優(yōu)雅,被很多團(tuán)隊(duì)采納!
吊炸天的 Docker 圖形化工具:Portainer,必須推薦給你!
最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊(cè)》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。
朕已閱 
評(píng)論
圖片
表情

