数据库回表与覆盖索引

回表

oracle中有有一个很明显的物理ID,叫做rowid,这个是全局唯一的.
rowid是物理结构上的,在每条记录insert到数据库中时都会有
一个唯一的物理记录.

回表:当查询数据时,在索引中查找到该行索引后,根据索引
获得该行的rowid,根据rowid再查询表中数据就是回表.

demo

SELECT c1,c2,c3  FROM TEST_TABLE WHERE c1=1  
如果c1列建立了索引。首先会从索引里面根据c1=1 查找出c1的rowid,然后根据rowid去找到数据块中对应的数据,将c1,c2,c3 查出来。

如果c1没有建立索引,那就需要进行全表扫描。到数据块中扫描一番,这样性能不好。

覆盖索引(不需要回表操作)

MySQL可以利用索引返回SELECT 列表中的字段。而不必根据索引再次读取数据文件。包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index)
。也就是平时所说的不需要回表操作。

判断标准:

在查询前面使用explain,可以通过输出的extra列来判断,对于一个索引覆盖查询,显示为using index,MySQL查询优化器在执行查询前会决定是否有索引覆盖查询。
也就是说当前查询所需要的数据直接就可以在索引里面查得到。有时候根据业务,建立多列索引,使用覆盖索引,可以取得相当好的性能优化

回表为什么慢

回表是磁盘IO,而磁盘IO远远慢于内存操作
主要原因还是随机IO,增加了磁盘 IO的次数,
所以mysql针对大表扫描都有MRR优化策略.

参考

读了有收获就请肥宅喝瓶怡宝吧!