指的是在进行查询时,首先通过索引定位到对应页,然后再根据行的物理地址找到所需的数据行。换句话说,回表是指根据索引查询到的主键值,再去根据主键索引获取完整的数据记录。
如:
一张表: id,name, age, gender, address
其中id主键,name普通索引;
执行:
select * from user where name = "牛马"
查询过程:
首先根据name的值去name的B+树上查询,获取到对应的主键id,再根据id的值去id的B+树上去查询整行的记录,这个过程就称之为 回表,同时查找了两棵树;
回表效率低,很多时候查询慢就是因为大量的回表操作。
覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询的列要被所建的索引覆盖。
如:
一张表: id,name, age, gender, address
其中id主键,name普通索引;
执行:
select id, name from user where name = "牛马"
查询过程:
直接根据name的值去name的B+树上查找即可,因为name的B+树上包含了全部需要查询的信息,不需要回表。这也就是为什么平时都说不要使用 select * 的原因之一,因为如果查询命中合适的覆盖索引,那查询效率就会高很多。
覆盖索引效率高,推荐使用,也是一种优化查询效率的手段;
是指在联合索引中,如果你的 SQL 语句中用到了联合索引中的最左边的索引,那么这条 SQL 语句就可以利用这个联合索引去进行匹配。
如:
一张表: id,name, age, gender, address
其中id主键,name,age和gender为联合索引;
#这样可以利用到定义的索引(name,age,gender),用上name,age,gender
select * from user where name="牛马" and age=1 and gender=1;
#这样可以利用到定义的索引(name,age,gender),用上name,age
select * from user where name="牛马" and age=1;
#这样可以利用到定义的索引(name,age,gender),用上name,age(mysql有查询优化器)
select * from user where age=1 and name="牛马";
#这样也可以利用到定义的索引(name,age,gender),用上name
select * from user where name="牛马";
#这样不走索引(name,age,gender)
select * from user where age=1 and gender=1;
#这样可以利用到定义的索引(name,age,gender),但只用上name索引
select * from user where name="牛马" and gender=1;