在MySQL中,如何使用覆盖索引优化limit分页查询?
MySQL Limit 语法格式:分页查询时,我们会在LIMIT 后面传两个参数,一个是偏移量(offset),一个是获取的条数(limit)。当偏移量很小时,查询速度很快,但是当 offset 很大时,查询速度就会变慢。例如,假设有一张 300w 条数据的表,对其进行分页查询,可以看到,随着偏移量(offset)的增加,查询时间变得越长。对于普通的业务而言,超过1秒的查询是绝对不可以忍受的。上例中,当偏移的起始位置超过10万时,分页查询的时间超过61秒。当偏移量超过100万时,查询时间竟然长达273秒。
从上例中,我们可以总结出:LIMIT分页查询的时间与偏移量值成正比。当偏移量越大时,查询时间越长。这种情况,会随着业务的增加,数据的增多,会越发的明显。那么,如何优化这种情况呢?答案是,覆盖索引。
对于LIMIT分页查询的性能优化,主要思路是利用覆盖索引字段定位数据,然后再取出内容。不使用覆盖索引,查询耗时情况如下:
缺点是,不适用于结果集不以ID连续自增的分页场景。在复杂分页场景,往往需要通过过滤条件,筛选到符合条件的ID,此时的ID是离散且不连续的。如果使用上述的方式,并不能筛选出目标数据。当然,我们也可以对此方法做一些改进,首先利用子查询获取目标分页的ids,然后再根据 ids 获取内容。然而,并不尽人意。我们得到一个错误提示。错误信息的含义是,子查询不能有 limit操作。于是,我们对SQL进行了改造,对子查询包了一层。
执行成功,且查询效率很高。但是,这种写法非常繁琐。我们可以使用下面的join 分页方式,达到相同的优化效果。实际上,两者的原理是相同的。
如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作。简单的说,覆盖索引覆盖所有需要查询的字段(即,大于或等于所查询的字段)。MySQL可以通过索引获取查询数据,因而不需要读取数据行。
覆盖索引的好处:
通过利用覆盖索引,能极大的优化了Limit分页查询的效率。在真正的实践中,除了使用覆盖索引,优化查询速度外,我们还可以使用 Redis 缓存,将热点数据进行缓存储存。背景描述的事故,我们考虑了时间成本和业务复杂度后,最后采取的是*分页和增加缓存。所谓的*分页,即在不影响阅读体验的前提下,只允许用户可以查看前几千条的数据。经测验,偏移量较小时的查询效率较令人满意,查询效率接近使用覆盖索引查询的速度。
本文如未解决您的问题请添加抖音号:51dongshi(抖音搜索懂视),直接咨询即可。