mysql 虚拟列
09 August 2018

虚拟列 Generated Column

alter table DB.TABLE add COL int generated always as (xxx) virtual/stored;

virtual 表示 Generated Column 将生成的方式保存在数据库的元数据中
stored 表示 Generated Column 将数据直接存储在数据库中

给虚拟列添加索引

mysql> alter table DB.TABLE add index idx (xxx);

加了虚拟列的索引之后,即使是一个 func ,也会走这个索引。例如

mysql> alter table tb add index idx (left(name, 70));
mysql> explain select * from tb where left(name, 70) = 'xxx';

可以看到 possible_keys 会多一个虚拟列对应的索引

工作中遇到个需求,一开始 log 表的 content 字段存储的是一个 json 字符串,需求是找出某个 obj_id 下用户的操作记录,一开始的代码是这样的

$cond = "{\"obj_id\":\"{$obj_id}\",\"user\":\"{$user}\"%}";
getLogList("content LIKE '{$cond}'");

幸运的是 obj_iduser 的长度刚好都是固定的,索性给 left(content, 70) 加了虚拟列,通过 explain 和 select 观察运行结果,可以看到有一点小提升。比直接走 content 的左前缀索引还快

$cond = "{\"obj_id\":\"{$obj_id}\",\"user\":\"{$user}\"";
getLogList("left(content, 70) = '{$cond}'");