程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> mysql同時使用orderby和limit查詢時的一個嚴重隱患--丟失數據

mysql同時使用orderby和limit查詢時的一個嚴重隱患--丟失數據

編輯:MySQL綜合教程

mysql同時使用orderby和limit查詢時的一個嚴重隱患--丟失數據


我經常使用order by和limit來做數據分頁顯示並排序,一直也沒發現過什麼問題。但這兩天缺遇到一個嚴重的問題,在按時間戳升序排列並用limit分批讀取數據時,卻發現在某些記錄丟失了,表中明明有的記錄確死活讀取不到。研究了大半天終於發現了問題所在,記錄一下以防忘記,也是給大家提個醒。

問題重現

工具和原料

數據庫:

Ver 14.14 Distrib 5.6.11, for Linux (x86_64) using EditLine wrapper

表結構:

字段 類型 說明 id int(10) 主鍵 pay_time int(10) 時間戳,有索引 flag tinyint(1) 類型標識,用於分類篩選

數據

大概5000條數據, 大部分記錄的flag都等於0,pay_time字段時間戳格式都正確

需求

篩選出flag=0的記錄,按pay_time升序依次讀取所有數據。

處理方式

使用limit分批讀取數據,如:
select id, pay_time from order_customer_new where flag=0 order by pay_time asc, id asc limit 250, 10;

發現問題

在讀取數據的過程中,發現有時間戳相等的記錄,分兩次讀取出來時,可能會丟失一條記錄。見下圖,id=465的記錄就丟失了。

圖1

這裡寫圖片描述

問題分析與猜測

當排序值相等,其先後順序的不確定的。這裡我猜想:當465和466處於limit末尾時466排在前面,而當處於limit開頭時,466缺排到後面去了。所以465丟失了,466出現了兩次。
排序值相等時,其順序的不確定應該是其結果不可預測。但真正進行排序時應該會采取一定的規則以確定唯一的排序結果,也就是說,即使有相等的排序值,多次排序的結果應該是一樣的。從以前的使用經歷看,mysql是這麼做的。但這次遇到的問題似乎說明mysql並不是這樣的。不知道mysql本來就是如此,還是一個bug。

解決辦法

既然猜想此問題是因為排序值相等造成順序不確定引起的,那麼就試試增加排序條件讓其排序結果是確定的、唯一的。一試果然OK,如下圖所示,465出來了。

這裡寫圖片描述

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved