mysql order by limit



If you use LIMIT row_count with ORDER BY, MySQL ends the 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 must be selected, and most or all of them must be sorted, before it can be ascertained that the first row_count rows have been found. In either case, after the initial rows have been found, there is no need to sort any remainder of the result set, and MySQL does not do so.
..用limit必须排序,


为什么Limit 必须要使用order by?


limit中没有排序,是按照数据库存储顺序取出的。
如果需要按一定的顺序取,比如说从小到大,就需要使用order by。
http://dev.mysql.com/doc/refman/5.5/en/limit-optimization.html
http://dev.mysql.com/doc/refman/5.1/en/limit-optimization.html
http://hackmysql.com/case3

https://search.oracle.com/search/search?q=LIMIT optimization&group=MySQL&x=0&y=0

http://dev.mysql.com/doc/refman/5.1/en/limit-optimization.html


深层原因: SQL语句中如果包含limit N,必须带有Order By语句,否则会导致返回结果的随机性。因此,一个集群中不同的mysql实例返回结果会产生差。

 

解决办法:SQL语句包含limit的,必须含有order by



如果要使用order by?


  • MySQL does not support LIMIT in subqueries for certain subquery operators:

    mysql> SELECT * FROM t1
        ->   WHERE s1 IN (SELECT s2 FROM t2 ORDER BY s1 LIMIT 1);
    ERROR 1235 (42000): This version of MySQL doesn't yet support
     'LIMIT & IN/ALL/ANY/SOME subquery'


http://dev.mysql.com/doc/refman/5.1/en/replication-features-limit.html







在Mysql数据库中,现在有一张表weekday,主键是id,执行sql语句select * from weekday where id in (id1,id2, ……,idn),结果是否如下呢?

id1 ……

id2 ……

…………

idn ……

答案是不一定,也不要被眼前的假象所蒙蔽。因为笔者在不久前就遇到这样一个问题,在测试环境中简单的执行了上面语句,得到了按ID顺序排列的结果,于是基于如此结果做了后面的逻辑处理,但是在线上环境,得到了完全不同的结果,也导致了后面的逻辑处理出现了问题。

这是一个比较容易忽略的问题,往往比较依赖测试环境,殊不知,测试环境有时候与线上环境差距还是很大的。

这里简单的说一下,这张weekday表在两个不同环境上,使用show create table weekday命令,两者均为MyISAM存储引擎,得到的结果是完全一样的,但是:

(1)测试环境下的数据库是单机模式的,线上环境的数据库是主从式,查询语句使用从库

(2)从weekday中数据的灌入角度来看,从库中的数据是根据主库数据的binlog文件由mysql自动同步产生的,而测试环境中的数据是,由线上库数据导入的。要说的是,从库中数据的产生,是存在一定的延迟的,所以从库数据的插入顺序并不能保证与主库中数据的插入顺序保持一致

以上差异是导致两种环境出现不同结果的原因,那么权威解释呢?在MYSQL的官方网站上,找答案。

这涉及到Mysql的默认排序模式,简单的说就是使用MyISAM存储引擎,在不指定Order by的情况下,数据的默认排序是数据插入顺序,而使用InnoDB存储引擎,数据的默认排序是主键的顺序。更深层次的原因很复杂,涉及 MyISAM是以B-树作为数据结构,InnoDB以B+数作为数据结构,同时还与'Table Scan有关'。


不过对于以上原因,有兴趣的可以去了解。从中总结的教训是什么呢?

(1)不要依赖于默认排序(2)当你想要的结果是有序的,那么一定使用Order By (3)Limit往往与顺序有关,所以在使用Limit时,建议要与Order by同时使用。

也许有人会问,使用Order By,就与性能有关了,是的。如果Order By没有使用索引,就是全表的文件排序,所以在使用时要注意到性能上的优化。






前不久遇到一个问题,mysql Sql上的order by 和limit相干。

一般RD在写与时间相关的sql语句时,大多数都会用到order by。如现在有一个均是工作日的表:weekday, 获取2014-11-23后的10天,可以很简单:

select * from weekday where time > '2014-11-23' order by time limit 10; 这时候的返回结果是有序的,如果将这个里的返回结果中的id 组成串,如(33279,,*)再穿入进行查询。

即 select * from weekday where id in (idStrs) 会发生什么呢? 是否会按照id的顺序输出呢?

答案是不一定,也不要被眼前所欺骗

这涉及到Mysql中的默认排序,

* Do not depend on order when ORDER BY is missing.  不要依赖于排列,如果没有使用Order By
* Always specify ORDER BY if you want a particular order -- in some situations the engine can eliminate the ORDER BY because of how it does some other step.   当你需要特定顺序时,就要Order by
* GROUP BY forces ORDER BY. (This is a violation of the standard. It can be avoided by using ORDER BY NULL.) 

SELECT * FROM tbl -- this will do a "table scan". If the table has never had any DELETEs/REPLACEs/UPDATEs, the records will happen to be in the insertion order, hence what you observed.  
If you had done the same statement with an InnoDB table, they would have been delivered in PRIMARY KEY order, not INSERT order. Again, this is an artifact of the underlying implementation, not something to depend on.


但是这个时候,如果之前已经




http://forums.mysql.com/read.php?21,239471,239688

工作日表的Engine是MyISAM. 




Re: What is The Default Sort Order of SELECTS with no ORDER BY Clause?
Posted by:  Rick James ()
Date: December 23, 2008 01:39AM

* Do not depend on order when ORDER BY is missing. 
* Always specify ORDER BY if you want a particular order -- in some situations the engine can eliminate the ORDER BY because of how it does some other step. 
* GROUP BY forces ORDER BY. (This is a violation of the standard. It can be avoided by using ORDER BY NULL.) 

SELECT * FROM tbl -- this will do a "table scan". If the table has never had any DELETEs/REPLACEs/UPDATEs, the records will happen to be in the insertion order, hence what you observed. 

If you had done the same statement with an InnoDB table, they would have been delivered in PRIMARY KEY order, not INSERT order. Again, this is an artifact of the underlying implementation, not something to depend on.

你可能感兴趣的:(mysql order by limit)