一、update语句执行流程:

        语句执行前首先连接数据库,然后分析器通过词法和语法解析得到该语句是更新语句,优化器来决定使用哪个索引,然后执行器来执行:
1、执行器要取出where条件的行
2、判断数据页是否在内存中,在的话返回行数据,不在的话将在磁盘中读出所在页然后再返回行数据
3、对行数据进行update
4、写入新行
5、新行更新到内存
6、将update操作写入redo log,redo log处于prepare状态
7、写binlog
8、提交事务,redo log处于commit状态,更新完成

二、分析器的工作:

1、把关键字提取出来得到该sql是什么语句,然后把字符串“t”识别成“表名 t”,把字符串“ID”识别成“列 ID”等;

2、由上述得到的结果,根据语法规则,判断该SQL是否满足MySQL语法。

三、优化器的工作:

        优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。

        但优化器有时候会选错索引,这个之后会另起一篇文章讨论为何优化器会出现选错索引的情况,并且我们如何避免这个问题导致一条本该执行很快的sql变慢。

四、Update语句是写redo log的,在4种情况下会将redo log做的更新写入磁盘:

1、InnoDB的redo log写满了。这时候就需要推进checkpoint,在这种情况下,系统会停止所有更新操作,等redo log留出空间之后就可以继续写。
2、系统的内存空间不足,此时脏页太多,需要将脏页flush
3、MySQL认为系统空闲时
4、MySQL正常关闭前会把内存的脏页flush到磁盘上,等到下次启动MySQL时就可以直接从磁盘读数据
        其中情况1、2对于业务影响较大。

五、此处引起我对于InnoDB内存管理使用的页面置换策略的思考:

        由于InnoDB有预读机制,如果只是简单使用的是LRU策略,是否因为预读失败导致磁盘IO频繁,如果使用了buffer pool,预读机制也有可能会导致buffer pool被污染。
        在查找资料后得知,InnoDB加入了一个参数innodb_old_blocks_time来优化,预读进入buffer pool的页优先进入old sublist,当数据页被访问且在old sublist停留时间超过设定值时,才会进入new sublist,这样就可以防止批量扫描大量数据时,可能会使得大量的热数据被置换出去,导致MySQL性能下降。