mysql中order by和limit混用時出現的問題

sql:mysql

SELECT
	D.authen_state,
	D.developer_id,
	D.real_name,
	D.address,
	D.phone_num,
	D.developer_id_type,
	D.enterprise_detail_id,
	D.create_time,
	D.update_time,
	D.is_avail
FROM
	aisv_g_developer_detail D
ORDER BY
	authen_state ASC
LIMIT 30,10

問題:分頁查詢數據,不一樣頁之中出現了相同的數據。sql

緣由:這是Mysql5.7以上的優化優化

官方文檔:this

If you combine LIMIT row_count with ORDER BY, MySQL stops sorting as soon as it has found the first row_count rows of the sorted result, rather than sorting the entire result. If ordering is done by using an index, this is very fast. If a filesort must be done, all rows that match the query without the LIMIT clause are selected, and most or all of them are sorted, before the first row_count are found. After the initial rows have been found, MySQL does not sort any remainder of the result set.
One manifestation of this behavior is that an ORDER BY query with and without LIMIT may return rows in different order, as described later in this section.

翻譯:若是你將Limit row_count與order by混用,mysql會找到排序的row_count行後立馬返回,而不是排序整個查詢結果再返回。若是是經過索引排序,會很是快;若是是文件排序,全部匹配查詢的行(不帶Limit的)都會被選中,被選中的大多數或者所有會被排序,直到limit要求的row_count被找到了。若是limit要求的row_count行一旦被找到,Mysql就不會排序結果集中剩餘的行了。翻譯

若是order by的字段有多個行都有相同的值,mysql是會隨機的順序返回查詢結果的,具體依賴對應的執行計劃。也就是說若是排序的列是無序的,那麼排序的結果行的順序也是不肯定的。code

根據這個咱們大概知道爲何會分頁不許了,由於sql中的authen_state存在相同的行,在實際執行時返回結果對應的行的順序是不肯定的。xml

解決方案:若是想在limit存在或者不存在的狀況下,都保證結果相同,能夠在後面再加上一個排序條件,例如id字段是惟一的,能夠在排序字段中額外加上以確保順序穩定。排序

因此最終的sql以下:索引

SELECT
	D.authen_state,
	D.developer_id,
	D.real_name,
	D.address,
	D.phone_num,
	D.developer_id_type,
	D.enterprise_detail_id,
	D.create_time,
	D.update_time,
	D.is_avail
FROM
	aisv_g_developer_detail D
ORDER BY
	authen_state ASC,developer_id
LIMIT 30,10
相關文章
相關標籤/搜索