在分页系统中使用limit和offset是很常见的,它们通常也会和ORDER BY一起使用。索引对排序较有帮助,如果没有索引就需要大量的文件排序。
一个常见的问题是偏移量很大,比如查询使用了LIMIT 10000,20 ,它就会产生10020行数据,并且丢失掉前10000行。
一个提高效率的简单技巧就是在覆盖索引上进行偏移,而不是全行数据进行偏移。可以讲从覆盖索引上提取出来的数据和全行的数据进行联接,然后取得需要的列。这样会更有效率,如:
SELECT film_id, description FROM sakila.film ORDER BY title LIMIT 50, 5;
如果表非常大,这个查询最好写成下面的样子:
SELECT filem.file_id, file.description from sakila.film INNER JOIN (SELECT film_id FROM sakila.film ORDER BY title LIMIT 50,5 )AS lim USING (film_id);
(个人感觉使用了覆盖索引(title)或(film_id,title))
这种方式效率更高,它让服务器在索引上面检查尽可能少的数据,一旦取得了所需要的行,就把它们联接到完整的表上面,并取出其余的列。类似的技巧可以应用到有LIMIT子句的联接上面。
Laravel上的实现:Model::offset(1000)->limit(20)->get()
本文有百牛信息技术bainiu.ltd整理于博客园