延迟关联:通过使用覆盖索引查询返回需要的主键,再根据主键关联原表获得需要的数据。
为什innodb的索引叶子节点存的是主键,而不是像myisam一样存数据的物理地址指针?
如果存的是物理地址指针不就不需要二次查找了吗,根据myisam和innodb数据存储方式的差异去想
Imyisam索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。
而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。
这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。
innodb为了避免二次查找可以使用索引覆盖技术,无法使用索引覆盖的,就使用基于索引覆盖实现延迟关联;
一般查询:
order by col limit N,OFFSET M , MySQL 执行此类sql时需要先扫描到N行
select goods_id,name from sm_goods_all order by goods_id limit 1000000, 10
10 rows retrieved starting from 1 in 3s 611ms (execution: 3s 603ms, fetching: 8ms)
延迟关联查询:
select g1.goods_id, g1.name from sm_goods_all g1, (SELECT goods_id FROM sm_goods_all ORDER BY goods_id LIMIT 1000000, 10) g2 where g1.goods_id=g2.goods_id
10 rows retrieved starting from 1 in 246ms (execution: 236ms, fetching: 10ms)
select goods_id,name from sm_goods_all
where goods_id >= (select goods_id from sm_goods_all order by goods_id asc limit 1000000,1) limit 10
10 rows retrieved starting from 1 in 246ms (execution: 234ms, fetching: 12ms)
数据量大的情况下,延迟关联比一般查询快了10陪
参考: