1.索引能极大地减少扫描行数,加快查询速度
因为B+树索引是一种排好序的,可用于快速查找的数据结构,因为当我们查找特定数据时,往往只需几次IO;
2.索引可以帮助服务器避免排序和临时表
当我们正常运行 sql 语句的时候,如果不使用索引运行下面这条语句:
SELECT * FROM user order by age desc;
MySQL 的流程是这样的
- 扫描所有行,把所有行加载到内存后
- 再按 age 排序生成一张临时表,再把这表排序后将相应行返回给客户端,
- 更糟的,如果这张临时表的大小大于 tmp_table_size的值(默认为 16 M),内存临时表会转为磁盘临时表,性能会更差;
但是如果加了索引,索引本身是有序的,所以从磁盘读的行数本身就是按 age 排序好的,也就不会生成临时表,就不用再额外排序 ,无疑提升了性能。
3.索引可以将随机 IO 变成顺序 IO
什么是顺序IO和随机IO
顺序IO是指读写操作的访问地址连续。在顺序IO访问中,HDD所需的磁道搜索时间显着减少,因为读/写磁头可以以最小的移动访问下一个块。数据备份和日志记录等业务是顺序IO业务。
随机IO是指读写操作时间连续,但访问地址不连续,随机分布在磁盘的地址空间中。产生随机IO的业务有OLTP服务,SQL,即时消息服务等。
① 顺序I/O一般只需扫描一次数据、所以、缓存对它用处不大
② 顺序I/O比随机I/O快
③ 随机I/O通常只要查找特定的行、但I/O的粒度是页级的、其中大部分是寻址,耗费时间,顺序I/O所读取的数据、通常发生在想要的数据块上的所有行更加符合成本效益。 所以、缓存随机I/O可以节省更多的workload
因为MYSQL是属于随机IO业务类型的,但是我们通过索引技术,让随机IO变成了顺序IO;
先看顺序写,如果你有自增主键,并且没有其他索引的情况下,那么此时就是顺序写的,因为插入的数据是自增的,b+树会尽量放在同一个页中;
再看顺序读,如果你想查询>10的记录,由于数据以及是排好序的,因此访问时,是按照顺序来读取的;
如果是查询的非聚簇索引,则是随机读,因为需要先查找到主键值,然后回表,该过程就是随机IO
但是我们可以通过MRR(Multi Range Read)来进行优化!!
举例说明: salary字段上有二级索引,但是select * ,因此需要回表,MRR优化就是把把通过二级索引查出的主键进行排序,这样访问聚集索引时就是有序的!!
随机 IO 和顺序 IO 大概相差百倍 (随机 IO:10 ms/ page, 顺序 IO 0.1ms / page),可见顺序 IO性能之高,索引带来的性能提升显而易见!