当前位置: 首页 > 科技观察

Mysql分页&关联查询优化

时间:2023-03-12 00:33:37 科技观察

优化关联查询全书基本都在讨论这个话题。这里需要说明的是:确保ON或USING子句中的列上有索引。创建索引时必须考虑关联顺序。当A表和B表关联c列时,如果优化器的关联顺序是B,A,那么B表对应的列就不需要建索引了,没有用到的索引只会额外创建高架。一般来说,除非你有其他原因,你只需要在连接顺序中的第二个表的相应列上创建索引。确保任何GROUPBY和ORDERBY表达式仅引用一个表中的列,以便MySQL可以使用索引来优化该过程。升级MySQL时需要注意:关联语法、运算符优先级等可能发生变化的地方。因为以前是普通联想的地方可能会变成笛卡尔积,不同类型的联想可能会产生不同的结果。优化LIMIT分页当系统中需要进行分页操作时,我们通常采用LIMIT加offset的方式来实现,同时加入适当的ORDERBY子句。如果有相应的索引,效率通常是好的,否则,MySQL需要做大量的文件排序操作。一个很常见也很麻烦的问题就是注意“当offset很大的时候,比如可能是LIMIT1000,20这样的查询,这时候MySQL需要查询10020条记录,只返回***20,前10000条记录会被丢弃,这是非常昂贵的。如果所有页面访问频率相同,那么这样的查询平均需要访问表的一半数据。要优化这个查询,要么在限制数量pagesinpages,oroptimizetheperformanceoflargeoffsets.优化此类分页查询最简单的方法之一是尽可能使用索引覆盖扫描,而不是查询所有列。然后根据需要做关联操作返回需要的columns.当offset很大的时候,这个的效率会大大提高。考虑以下查询:mysql>SELECTfilm_id,descriptionFROMsakila.filmORDERBYtitleLIHIT50,5;如果表很大,那么查询***可以改写如下:mysql>SELECTfilm.film_id,Film.description->FROMsakila.film->INNERJOIN(->SELECTfilm.film_idFROMsakila.film->ORDERBYtitleLIMIT50,5->)ASlimUSING(电影编号);这里的“延迟关联”会大大提高查询效率,它让MySQL扫描尽可能少的页,然后根据关联的列获取需要访问的记录,返回原表查询所有列必需的。此技术还可用于优化关系查询中的LIMIT子句。有时也可以将LIMIT查询转换为已知位置的查询,这样MySQL就可以通过范围扫描得到相应的结果。例如position列上有索引,边界值是预先计算好的,上面的查询可以改写为:mysql>SELECTfilm_id,descriptionFROMsakila.Film->WHEREpositionBETWEENsoAND540RDERBYposition;排序数据的问题类似,但往往与GROUPBY同时结合使用。在这种情况下,通常需要预先计算并存储排名信息。LIMIT和OFFST的问题其实是OFFSET的问题。它会导致MySQL扫描大量不需要的行,然后丢弃它们。如果可以用书签记录上次取数据的位置,那么下次就可以直接从书签记录的位置开始扫描,这样就可以避免使用OFFSET。比如需要根据租约记录翻页,可以根据上一条租约记录向后追溯。这种做法是可行的,因为租约记录的主键是单调递增的。首先使用下面的查询得到第一组结果:mysql>SELECT*FROMsakila.rental->ORDERBYrentalidDESCLIMIT20;假设上面的查询返回的出租记录的主键范围是16049到16030,那么下一页的查询就是可以从16030这个点开始:mysql>SELECT*FROMsakila*rental->WHERErentalid<16030,->ORDERBYrentalidDESCLIMIT20;这种技术的好处是无论页面翻到多远,它的性能都会非常好。其他优化包括使用预先计算的汇总表,或链接到仅包含主键列和需要排序的数据列的冗余表。您还可以使用Sphinx来优化一些搜索操作,有关详细信息,请参阅附录F。