假设现在有一张表记录了每个人的基本信息
create TABLE `t_people` ( `id` INT(11) DEFAULT NULL , `name` VARCHAR(20) DEFAULT NULL , `age` INT(11) DEFAULT NULL , `info` VARCHAR(255) DEFAULT NULL )ENGINE = InnoDB;
里面总共有三条数据
INSERT INTO test.t_people (id, name, age, info, name_fist) VALUES (1, '张三', 8, null, '张'); INSERT INTO test.t_people (id, name, age, info, name_fist) VALUES (2, '李四', 12, null, '李'); INSERT INTO test.t_people (id, name, age, info, name_fist) VALUES (3, '张三', 11, null, '张');
现在我们需要找出姓名开头是张且年龄等于8的数据。
一、我们很容易想到给表添加名字和年龄的联合索引。
ALTER TABLE t_people ADD INDEX name_age_index(name, age);
搜索语句:
EXPLAIN SELECT * FROM t_people WHERE name LIKE '张%' AND age=8;
执行结果如下,总共扫描了2行

二、使用虚拟列
ALTER TABLE t_people add name_fist VARCHAR(2) GENERATED ALWAYS as (left(name,1)),ADD INDEX name_fist_age_index(name_fist, age);
语句如下:
EXPLAIN SELECT * FROM t_people WHERE name_fist='张' AND age=8;
执行结果如下,只扫描了1行

总结:
1.虚拟列在插入的时候不能指定值,更新的时候也不能主动修改,它的值会根据定义自动修改。
2.查询优化的过程往往就是较少扫描行数的过程。
Visits: 2511