延遲關聯:通過使用覆蓋索引查詢返回需要的主鍵,再根據主鍵關聯原表獲得需要的數據。
為什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 fromsm_goods_all g1, (SELECT goods_id FROM sm_goods_all ORDER BY goods_id LIMIT 1000000, 10) g2where g1.goods_id=g2.goods_id
10 rows retrieved starting from 1 in 246ms (execution: 236ms, fetching: 10ms)
select goods_id,name fromsm_goods_allwhere goods_id >= (select goods_id from sm_goods_all order by goods_id asc limit 1000000,1)
limit10
10 rows retrieved starting from 1 in 246ms (execution: 234ms, fetching: 12ms)
數據量大的情況下,延遲關聯比一般查詢快了10陪
參考: