SQL--LIMIT

提前终止查询

SELECT * FROM labels WHERE label='iwpfdc';
SELECT * FROM labels WHERE label='iwpfdc' LIMIT 1;

优化LIMIT分页

        处理分页会使用到LIMIT,当翻页到非常靠后的页面的时候,偏移量会非常大,这时LIMIT的效率会非常差。例如对于LIMIT 10000,20这样的查询,MySql需要查询10020条记录,将前面10000条记录抛弃,只返回最后的20条。这样的代价非常高,如果所有的页面被访问的频率都相同,那么这样的查询平均需要访问半个表的数据。

  优化此类分页查询的一个最简单的办法就是尽可能地使用索引覆盖扫描,而不是查询所有的列。然后根据需要与原表做一次关联操作返回所需的列。对于偏移量很大的时候,这样的效率会提升非常大。考虑下面的查询:

SELECT film_id, description FROM sakila.film ORDER BY title LIMIT 50, 5;

  如果这个表非常大,那么这个查询最好改写成下面的这样子:

SELECT film.film_id, film.description FROM sakila.film
INNER JOIN 
(SELECT film_id FROM sakila.film ORDER BY title LIMIT 50,5) AS lim
USING(film_id);

  注意优化中关联的子查询,因为只查询film_id一个列,数据量小,使得一个内存页可以容纳更多的数据,这让MySQL扫描尽可能少的页面。在获取到所需要的所有行之后再与原表进行关联以获得需要的全部列。
  LIMIT的优化问题,其实是OFFSET的问题,会导致MySql扫描大量不需要的行然后再抛弃掉。可以借助书签的思想记录上次取数据的位置,那么下次就可以直接从该书签记录的位置开始扫描,这样就避免了使用OFFSET。可以把主键当做书签使用,例如下面的查询:

SELECT * FROM sakila.rental ORDER BY rental_id DESC LIMIT 20;

  假设上面的查询返回的是主键为16049到16030的租借记录,那么下一页查询就可以直接从16030这个点开始:

SELECT * FROM sakila.rental WHERE rental_id < 16030 ORDER BY rental_id DESC LIMIT 20;

  该技术的好处是无论翻页到多么后面,其性能都会很好。此外,也可以用关联到一个冗余表的方式提高LIMIT的性能,冗余表只包含主键列和需要做排序的数据列

 

  

posted on 2020-05-10 14:44  溪水静幽  阅读(269)  评论(0)    收藏  举报