MySQL8.0对json进行了比较完善的支持, 咱们知道json具备比较特殊的存储格式,一般存在多个key value键值对,对于相似更新操做一般不会更新整个json列,而是某些键值。mysql
对于某些复杂的应用,json列的数据可能会变的很是庞大,这时候一个突出的问题是:innodb并不识别json类型,对它而言这些存储统一都是LOB类型,而在以前的版本中Innodb处理LOB更新的方式是标记删除旧记录,并插入新记录,显然这会带来一些存储上的开销(尽管Purge线程会去后台清理),而写入的redo log和Binlog的量也会偏高,对于超大列,可能会严重影响到性能。为了解决这个问题,MySQL8.0引入了LOB列部分更新的策略。sql
官方博客有几篇文章介绍的很是清楚,感兴趣的能够直接跳过本文,直接阅读官方博客:json
1: partial update of json values
2: introduces lob index for faster update
3: MVCC of Large Objectsmvc
以及相关的开发worklog:ide
WL#8963: Support for partial update of JSON in the optimizer
WL#8985: InnoDB: Refactor compressed BLOB code to facilitate partial fetch/update
WL#9141: InnoDB: Refactor uncompressed BLOB code to facilitate partial fetch/update
WL#9263: InnoDB: Enable partial access of LOB using multiple zlib streams
WL#8960: InnoDB: Partial Fetch and Update of BLOB
WL#10570: Provide logical diffs for partial update of JSON values
WL#2955: RBR replication of partial JSON updates函数
本文仅仅是笔者在理解该特性时作的一些简单的笔记,,记录的主要目的是用于之后若是涉及到相关的工做能够快速展开,所以比较凌乱sqlserver
目前partial update须要经过JSON_SET, 或者JSON_REPLACE等特定接口来进行json列的更新,而且不是全部的更新都可以知足条件:性能
空间足够大,能够容纳替换的新值fetch
下面以json_set更新json列为例来看看相关的关键堆栈spa
如上所述,须要指定的json函数接口才能进行partial update
mysql_execute_command |--> Sql_cmd_dml::execute |--> Sql_cmd_dml::prepare |--> Sql_cmd_update::prepare_inner |---> prepare_partial_update |-->Item_json_func::supports_partial_update
这里只是作预检查,对于json列的更新若是所有是经过json_set/replace/remove进行的,则将其标记为候选partial update的列(TABLE::mark_column_for_partial_update
), 存储在bitmap结构TABLE::m_partial_update_columns