走索引一定比全表扫描快吗?

user表中name是二级索引,id是主键索引

1
2
explain
select * from user where name = "Alice";

执行结果是进行了全表扫描,type=all

首先索引底层是由B+树实现的,B+树是一种数据结构,具体怎么使用索引是由Server层的sql优化器来决定,sql优化器它的作用就是制定执行方案,就是具体选择哪个索引,就是从所有可能的执行计划中选择成本最低的一个执行计划。

那么这个成本是什么呢?

成本分为CPU成本和I/O成本,因为像存储引擎的数据和索引都是存储在磁盘上的,我们要把它加载到内存当中进行增删改查,这个从磁盘加载到内存当中就是I/O成本;CPU成本是指对数据的搜索、条件判断、排序等这些操作的成本,这个就是CPU成本;其实这个成本是可以量化的,比如页是磁盘与内存交互的基本单位,MySQL规定了从磁盘中读取一个页面到内存所花费的成本是1,从内存中读取一个页面所花费的的成本是0.25,记录间比较成本是0.1,而索引键值的比较成本是0.05,是成本中最小的,等等还有其他成本,比如在磁盘中创建一张临时表,它的成本是20,在内存中创建一张临时表,它的内存是1等等。

如何查看执行计划所花费的成本呢?

1
2
explain format = json 
(select * from user where name = "Alice");

如何强制使用索引呢?

1
2
explain format = json 
(select * from user force index(name_index) where name = "Alice");

总结

使用索引的话造成回表次数太多,导致所花费的时间成本很高