前段時間遇到一個問題mysql查詢問題,當我們使用select * from xxxx_tbl order by col1 limit 0,5 時,如果col1在表中存在重複,那麼我們通過limit分頁查出來的資料就可能存在不全,或者重複。
案例
表結構如下:
字段 | 類型 | 注釋 |
---|---|---|
id | varchar(20) | 主鍵 |
col1 | varchar(20) | col1 |
col2 | varchar(20) | col2 |
col3 | varchar(20) | col3 |
全表查詢:
資料為:
id | col1 | col2 | col3 |
---|---|---|---|
15 | 5 | 9 | 10 |
12 | 2 | 5 | 6 |
14 | 2 | 7 | 8 |
16 | 2 | 4 | 5 |
11 | 1 | 2 | 3 |
其中col1字段不是唯一的,第二第三第四行的col1都是2。
分頁查詢第一頁:
查詢結果:
id | col1 | col2 | col3 |
---|---|---|---|
15 | 5 | 9 | 10 |
16 | 2 | 4 | 5 |
12 | 2 | 5 | 6 |
這裡就會發現,有limit和沒有limit查出來的順序就不一樣了。我們再來查第二頁:
查詢結果:
id | col1 | col2 | col3 |
---|---|---|---|
16 | 2 | 4 | 5 |
11 | 1 | 2 | 3 |
我們就會發現,16-2-4-5這條記錄在兩頁裡都出現了。而14-2-7-8,這條資料兩頁中都不存在。
原因
摘自mysql官方文檔有這麼一段話:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnLxADO4MzN1kTMyEjMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
意思是如果order by的字段有多個行都有相同的值,mysql是會随機的順序傳回查詢結果的,具體依賴對應的執行計劃(實際的sql是什麼)。也就是說如果排序的列是無序的,那麼排序的結果行的順序也是不确定的。
解決方案
既然官方文檔裡給出解釋了,那也就不必深究了,那解決方案有兩種:
- 使用唯一鍵作為排序字段
- 如果你一定要使用類似col1這樣的字段,那你可以在後面加一個輔助排序字段,形成排序組合: