不一样,这是MySQL中典型的深度分页的问题。
MySQL的limit m n工作原理就是先读取前面m+n条记录,然后抛弃前m条,然后返回后面n条数据,所以m越大,偏移量越大,性能就越差。
所以,limit 10000000,100要比limit 0,100的性能差的多,因为他要先读取10000100条数据,然后再抛弃前面的10000000条。
通常,我们在查询数据的时候,如果明确的知道我们想要多少行的话,那么建议大家在查询语句中使用limit,而不是把整个结果集查出来再自己丢弃那些不用的数据。
虽然我们前面提过,深度分页的时候,MySQL自己也是先全都查出来,再丢弃的,但是,MySQL针对limit也是有一些优化的。但是下面我们要介绍的优化前提都是使用limit的同时没有用having语句。
1、MySQL通常更愿意执行全表扫描,但是如果你用LIMIT只查询几行记录的话,MySQL在某些情况下可能会使用索引。
2、如果你将LIMIT rowcount子句与ORDER BY子句组合在一起使用的话,MySQL会在找到排序结果的rowcount行数据后后立即停止排序,而不是对整个结果进行排序。如果使用索引来完成排序,这将非常快。
当ORDER BY子句使用了索引时,MySQL就能够基于已经排好序的索引树快速找到所需的前N行数据,而不需要对整个表进行全表扫描和排序了。
3、如果LIMIT rowcount与DISTINCT一起使用,一旦找到rowcount惟一的行,MySQL就会停止。
4、LIMIT 0 可以快速返回一个空的结果集,这是用来检测一个查询是否有效的一种很有用的方法。
5、如果ORDER BY不走索引,而且后面还带了LIMIT的话,那么优化器可能可以避免用一个合并文件,并使用内存中的filesort操作对内存中的行进行排序。
我们知道,当我们在查询的时候,对某个字段order by时,如果这个字段有一些重复值,那么MySQL会是可以自由的以任意顺序返回这些行记录的,并且根据总体的执行计划而有有不同的表现。也就是说,排序结果可能是不固定的。
所以,当order by语句中,有Limit的时候,可能每次的查询结果都不一样。比如有下面两次查询的结果可能就不一样:
mysql> SELECT * FROM ratings ORDER BY category;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 3 | 2 | 3.7 |
| 4 | 2 | 3.5 |
| 6 | 2 | 3.5 |
| 2 | 3 | 5.0 |
| 7 | 3 | 2.7 |
+----+----------+--------+
mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+----+----------+--------+
| id | category | rating |
+----+----------+--------+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 4 | 2 | 3.5 |
| 3 | 2 | 3.7 |
| 6 | 2 | 3.5 |
+----+----------+--------+
那么该怎么解决呢?一个好的办法就是排序的时候不要只用一个字段,可以再加一个字段,比如id字段这种一定不会重复的。
mysql> SELECT * FROM ratings ORDER BY category,id LIMIT 5;