今天在说Mysql查询优化之前,我先说一个常见的面试题,并带着问题深入探讨研究。这样会让大家有更深入的理解。

一,Mysql数据库中一个表里有一千多万条数据,怎么快速的查出第900万条后的100条数据?

怎么查,谁能告诉我答案?有没有人想着,不就一条语句搞定嘛

select * from table limit 9000000,100;

那我们试试,去执行下这个SQL看看吧

 

 

看见了吗,查了100条数据用了7.063s。这能算的上是快速查询吗,估计没人能接受了这种速度吧!基于这个问题,我今天就要说说大数据时的快速查询了。

 

 


首先,我演示下大数据分页查询,我的test表里有1000多万条数据,然后使用limit进行分页测试:select * from test limit 0,100;

耗时:0.005s

select * from test limit 1000,100;

耗时:0.006s

select * from test limit 10000,100;

耗时:0.013s

select * from test limit 100000,100;

耗时:0.104s

select * from test limit 500000,100;

耗时:0.395s

select * from test limit 1000000,100;

耗时:0.823s

select * from test limit 5000000,100;

耗时:3.909s

select * from test limit 10000000,100;

耗时:10.761s

我们发现一个现象,分页查询越靠后查询越慢。这也让我们得出一个结论:

1,limit语句的查询时间与起始记录的位置成正比。

2,mysql的limit语句是很方便,但是对记录很多的表并不适合直接使用。

对大数据量limit分页性能优化

说到查询优化,我们首先想到的肯定是使用索引。利用了索引查询的语句中如果条件只包含了那个索引列,那在这种情况下查询速度就很快了。因为利用索引查找有相应的优化算法,且数据就在查询索引上面,不用再去找相关的数据地址了,这样节省了很多时间。另外Mysql中也有相关的索引缓存,在并发高的时候利用缓存就效果更好了。

我的test表使用InnoDB作为存储引擎,id作为自增主键,默认为主键索引。那我们现在用覆盖索引查询,看看效果如何:

SELECT id FROM test LIMIT 9000000,100;

总耗时4.256s,相对于7.063s少了很多。
现在优化的方案有两种,即通过id作为查询条件使用子查询实现和使用join实现;
1,id>=的(子查询)形式实现

select * from test where id >= (select id from test limit 9000000,1)limit 0,100 

耗时 4.262s;

2,使用join的形式;

SELECT * FROM test a JOIN (SELECT id  FROM