国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

小心避坑 MySQL分頁時出現的數據重復問題

2024-07-24 12:32:29
字體:
來源:轉載
供稿:網友
        問題描述
        在MySQL中我們通常會采用limit來進行翻頁查詢,比如limit(0,10)表示列出第一頁的10條數據,limit(10,10)表示列出第二頁。但是,當limit遇到order by的時候,可能會出現翻到第二頁的時候,竟然又出現了第一頁的記錄。
具體如下:
 
SELECT
 
  
`post_title`,
 
  
`post_date`
 
 
FROM
 
  post
 
 
WHERE
 
  
`post_status` =
'publish'
 
 
ORDER
BY
 
  view_count
desc
 
 
LIMIT
 
使用上述SQL查詢的時候,很有可能出現和LIMIT 0,5相同的某條記錄。而如果使用如下方式,則不會出現重復的情況:
 
SELECT
 
  *
 
 
FROM
 
  post
 
 
WHERE
 
  post_status =
'publish'
 
 
ORDER
BY
 
  view_count
desc
 
 
LIMIT
 
但是,由于post表的字段很多,僅僅希望用這兩個字段,不想把post_content也查出來。為了解決這個情況,在ORDER BY后面使用了兩個排序條件來解決這個問題,如下:
 
SELECT
 
  
`post_title`,
 
  
`post_date`
 
 
FROM
 
  post
 
 
WHERE
 
  
`post_status` =
'publish'
 
 
ORDER
BY
 
  view_count
desc,
 
  
ID
asc
 
 
LIMIT
 
按理來說,MySQL的排序默認情況下是以主鍵ID作為排序條件的,也就是說,如果在view_count相等的情況下,主鍵ID作為默認的排序條件,不需要我們多此一舉加ID asc。 但是事實就是,MySQL再order by和limit混用的時候,出現了排序的混亂情況。
1 分析問題
在MySQL 5.6的版本上,優化器在遇到order by limit語句的時候,做了一個優化,即 使用了priority queue。
使用 priority queue 的目的, 就是在不能使用索引有序性的時候,如果要排序,并且使用了limit n,那么只需要在排序的過程中,保留n條記錄即可,這樣雖然不能解決所有記錄都需要排序的開銷,但是 只需要 sort buffer 少量的內存就可以完成排序。
之所以MySQL 5.6出現了第二頁數據重復的問題, 是因為 priority queue 使用了堆排序的排序方法,而堆排序是一個不穩定的排序方法,也就是相同的值可能排序出來的結果和讀出來的數據順序不一致。
MySQL 5.5 沒有這個優化,所以也就不會出現這個問題。
也就是說,MySQL 5.5是不存在本文提到的問題的,5.6版本之后才出現了這種情況。
再看下MySQL解釋sql語言時的執行順序:
(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>
 
       執行順序依次為 form… where… select… order by… limit…,由于上述priority queue的原因,在完成select之后,所有記錄是以堆排序的方法排列的,在進行order by時,僅把view_count值大的往前移動。
       但由于limit的因素,排序過程中只需要保留到5條記錄即可,view_count并不具備索引有序性,所以當第二頁數據要展示時,mysql見到哪一條就拿哪一條,因此,當排序值相同的時候,第一次排序是隨意排的,第二次再執行該sql的時候,其結果應該和第一次結果一樣。

(編輯:武林網)

上一篇:MySQL子查詢

下一篇:mysql sysbench 1.0.X

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 霸州市| 丰城市| 彰化县| 南丰县| 福鼎市| 安义县| 陇南市| 博罗县| 兴城市| 五华县| 安陆市| 新津县| 和田县| 东源县| 财经| 贡觉县| 宿州市| 马边| 光泽县| 江华| 宾川县| 镇远县| 崇明县| 桂东县| 赫章县| 黄梅县| 禹城市| 大竹县| 静宁县| 兴和县| 通榆县| 河北省| 额敏县| 自治县| 奉节县| 嫩江县| 龙海市| 秭归县| 鄄城县| 黄冈市| 平武县|