1. 程式人生 > >同樣的sql,mysql 每次查詢結果順序不一致

同樣的sql,mysql 每次查詢結果順序不一致

  最近在專案遇到了一個問題就是,一個列表中排序的欄位比較多,並且有個匯出功能,因為匯出的 內容給別字段和列表中不一致啊,並且要求全部 匯出,沒有分頁,所以我沒有和列表公用一個數據源方法,在測試的時候發現了一個bug,就是我匯出的內容和列表中的內容的順序不一樣,這讓我很意外,然後我多次測試以後發現,我在列表中調整分頁大小的時候也會影響排序效果,這就比較尷尬了。開始我想怎麼分頁大小還影響排序效果了呢?mysql的執行順序是先執行排序在分頁的,所以這種猜測不對,查了些資料,發現是排序欄位中有相同內容的時候,mysql每次都隨機取一個,這就可能導致每次取出來的順序不一致,但是為什麼同樣的sql在mysql 客戶端執行沒有我問題呢?查詢了很多資料,也沒找到一個比較確認的理由,只是較多人認為是由於快取的存在。

一些比較官方的解釋:

根資料庫系統的演算法有關,早期版本的演算法是自然的多個執行緒二分法,那個執行緒先查到滿足條件的資料就先輸出出來,這樣就是亂序的,後期經過改進按照主鍵自然排序輸出。如果order by的值相同,一般是按自然排序,就是首個字元的字母或漢字的發音的首字母的s排序。

order by的欄位自然排序,如果你的order by 欄位是resort,resort值相同的情況下,是可能有兩種結果,一種就是你列出的隨機排序,還有一種就是按主鍵來排序。這個問題不是固定的,還可能跟你的伺服器效能都有關係,如果記憶體足夠大,執行mysql的時候會提供足夠大的緩衝池,也可能會出現另一種結果。

 所以很有可能是因為快取的存在,在mysql客戶端存在快取,然後每一次查詢都走快取所以他的順序不會發生改變。然而執行java程式順序不一致,可能就是因為沒有走快取,每一次都是實時查詢。也許java程式的這種結果本身就具有更多的可靠性。

那麼我們怎麼解決這個問題呢?

很簡單,他不是順序有時會不一致嗎,那我們再給他一個順序進行排序就好了。在order by 後面加上 id desc  , 那麼我們的查詢結果就是一致了的。