回表
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优化策略.