什么是覆盖索引
覆盖索引是指:查询用到的列(包括SELECT返回的列、WHERE/ORDER BY/GROUP BY用到的列),全部都能在同一个索引中找到,从而不用回表。
用id(主键)查询时,直接走聚簇索引,叶子节点本就存整行,一次索引扫描直接返回数据,性能高(这属于主键查询,不是典型覆盖索引场景)。
如果查询返回的列不在索引中,就会触发回表去聚簇索引查完整数据。
判断标志:
EXPLAIN的Extra出现Using index,就是用了覆盖索引。实践建议:尽量避免
SELECT *,把常用查询列放进联合索引,才能享受覆盖索引。
什么是 mysql 超长分页(深度分页)
指的是LIMIT的偏移量(offset)非常大的分页查询,比如:
SELECT * FROM orders ORDER BY id LIMIT 1000000, 10;MySQL 实际做的事:
沿索引顺序读前 100 万零 10 行
丢掉前 100 万行
只返回最后 10 行
扫描了 100 万零 10 行,实际只要 10 行。浪费就在这。
代价和 offset 成正比——offset 越大,要扫描、丢弃的行越多,越慢。
如何优化超长分页(深度分页)
一般分页查询时,可以通过覆盖索引+子查询形式优化
优化前(直接 SELECT *):
SELECT * FROM t ORDER BY id LIMIT 9000000, 10;优化后(覆盖索引+子查询):
SELECT * FROM t, (SELECT id FROM t ORDER BY id LIMIT 9000000, 10) a WHERE t.id = a.id;