介绍MySQL在进行分页时,不会跳过offset行,而是取offset+N行,然后丢弃之前的offset行,返回N行。比如limit10000,20。mysql排序提取10020条数据后,只返回20条数据,查询和排序的成本非常高。当offset很大时,效率很低,所以我们需要重写sql,用书签记录最后一次取数据的位置,过滤掉一些数据,比如下面语句SELECTid,name,descriptionFROMfilmORDERBYnameLIMIT1000,10;可以改SELECTid,name,descriptionFROMfilmWHEREname>'begin'ORDERBYnameLIMIT10;name为上次分页后的最大值。注意这个场景只适用于没有重复值的场景。Delayedassociationdelayedassociation:通过覆盖索引查询返回需要的主键,然后通过主键关联原表得到需要的数据SELECTid,name,descriptionFROMfilmORDERBYnameLIMIT100,5;id是主键值,name上有索引。这样每次查询都会先从name索引列中找到id值,然后回表查询所有数据。可以看出,有很多返回表实际上是不需要的。完全可以先从name索引中找到id(注意只查询id是不会返回表的,因为非聚集索引包含的值是索引列值和主键值),相当于从索引中获取所有的列值,不需要回表),然后再次关联表获取所有数据,所以可以改为SELECTfilm。id,name,descriptionFROMfilmJOIN(SELECTidfromfilmORDERBYnameLIMIT100,5)tempONfilm.id=temp.id反序查询如果查询的是最后一页,offset可能很大SELECTid,name,descriptionFROMfilmORDERBYnameLIMIT100000,10;改成反向分页,效率是不是快了很多?SELECTid,name,descriptionFROMfilmORDERBYnameDESCLIMIT10;二维码关注。转载本文请联系Java石塘公众号。
