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
相关文章
相关标签/搜索