先上简明结论:

当limit offset rows中的offset很大时,会出现效率问题,如下语句1应该改写为语句2:

语句1:select * from test where val=4 limit 300000,5;
 
 
语句2: 
select

* from test a inner join (select id from test where val=4 limit 300000,5) b on a.id=b.id;


 

 

以下为详细说明:


表结构:

复制代码
mysql> desc test; +--------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+---------------------+------+-----+---------+----------------+ | id | bigint(20) unsigned | NO | PRI | NULL | auto_increment | | val | int(10) unsigned | NO | MUL | 0 | | | source | int(10) unsigned | NO | | 0 | | +--------+---------------------+------+-----+---------+----------------+ 3 rows in set (0.00 sec) 
复制代码
id为自增主键,val为非唯一索引。

 

灌入大量数据,共500万:

复制代码
 mysql> select count(*) from test; +----------+ | count(*) | +----------+ | 5242882 | +----------+ 1 row in set (4.25 sec)
复制代码
我们知道,当limit offset rows中的offset很大时,会出现效率问题:

复制代码
mysql> select * from test where val=4 limit 300000,5; +---------+-----+--------+ | id | val | source | +---------+-----+--------+ | 3327622 | 4 | 4 | | 3327632 | 4 | 4 | | 3327642 | 4 | 4 | | 3327652 | 4 | 4 | | 3327662 | 4 | 4 | +---------+-----+--------+ 5 rows in set (15.98 sec)
复制代码
 为了达到相同的目的,我们一般会改写成如下语句:

 mysql> select * from test a inner join (select id from test where val=4 limit 300000,5) b on a.id=b.id;
 

复制代码
+---------+-----+--------+---------+ | id | val | source | id | +---------+-----+--------+---------+ | 3327622 | 4 | 4 | 3327622 | | 3327632 | 4 | 4 | 3327632 | | 3327642 | 4 | 4 | 3327642 | | 3327652 | 4 | 4 | 3327652 | | 3327662 | 4 | 4 | 3327662 | +---------+-----+--------+---------+ 5 rows in set (0.38 sec)
复制代码
时间相差很明显。