执行update语句,用没用到索引,区别大吗?( 二 )

从以上实验大致可以看出,是否用到索引,对于 update 语句执行速度影响还是很大的,具体表现如下:

  • 若在区分度较高的字段上添加索引,并以该字段为筛选条件进行更新,则无论是更新该字段还是其他字段,用到索引的更新都要快好多 。
  • 若在区分度很低的字段上添加索引,并以该字段为筛选条件进行更新,当更新其他字段时,有无索引区别不大,当更新这个区分度很低的字段时,用到索引的更新反而更慢 。
2.一些经验总结我们试着来解释下以上实验结果,首先来看下 update SQL 执行流程,大致如下:
  1. 首先客户端发送请求到服务端,建立连接 。
  2. 服务端先看下查询缓存,对于更新某张表的 SQL ,该表的所有查询缓存都失效 。
  3. 接着来到解析器,进行语法分析,一些系统关键字校验,校验语法是否合规 。
  4. 然后优化器进行 SQL 优化,比如怎么选择索引之类,然后生成执行计划 。
  5. 执行器去存储引擎查询需要更新的数据 。
  6. 存储引擎判断当前缓冲池中是否存在需要更新的数据,存在就直接返回,否则去从磁盘加载数据 。
  7. 执行器调用存储引擎 API 去更新数据 。
  8. 存储器更新数据,同时写入 undo log 、redo log 信息 。
  9. 执行器写 binlog ,提交事务,流程结束 。
也就是说,执行更新语句首先需要将被更新的记录查询出来,这也就不难理解为啥以区分度较高的字段为筛选条件进行更新,有索引的情况下执行更快 。
对于区分度很低的字段,用没用到索引则区别不大,原因是查询出将被更新的记录所需时间差别不大,需要扫描的行数差别不大 。当更新区分度很低的字段的字段时,因为要维护索引 b+ 树,所以会拖慢更新速度 。
之前也有讲过,虽然索引能加速查询,但索引也是有缺点的,那就是索引需要动态的维护,当对表中的数据进行增加、删除、修改时,会降低数据的维护速度 。本次实验结果也能论证这个结论 。
通过本次实验,我们也能得到一些索引相关经验:
  • 只为用于搜索、排序、分组、连接的列创建索引 。
  • 索引尽量建在区分度高的字段上,避免在区分度低的字段上建索引 。
  • 对经常更新的表避免创建过多的索引 。
  • 不要有冗余索引,会增加维护成本 。




推荐阅读