一、概述
回表是MySQL中的一个概念,指的是在使用索引进行查询后,需要回到原表中查找记录的情况。回表操作带来了额外的IO操作,影响查询性能,因此需要尽可能减少回表的次数。
二、回表的原因
回表的原因可以分为两种:
1.需要查询的字段不在索引中。
在MySQL中,如果使用索引查询一个表,那么MySQL会通过索引找到符合条件的记录,然后将这些记录的主键或者索引的值保存在一个临时表里面,再根据临时表里的主键或者索引的值,去原表中查询需要的字段。如果需要查询的字段不在索引中,就需要回到原表中查询。
-- 创建测试表 CREATE TABLE `test_table` ( `id` int(11) NOT NULL, `name` varchar(20) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 插入测试数据 INSERT INTO `test_table` VALUES (1,'Tom',18),(2,'Jerry',20),(3,'Lucy',19),(4,'Lily',21); -- 使用索引查询 EXPLAIN SELECT id,name FROM test_table WHERE name='Tom';
上面的查询会使用name索引查询,但是需要查询的字段不在索引中,因此需要回到原表中查询,产生回表操作。
2.需要查询的字段在索引中但是长度太大。
在MySQL中,每种存储引擎对于索引字段的长度都有限制。如果需要查询的字段在索引中但是长度太大,就可能会导致索引不能完全覆盖查询的所有字段,从而需要回到原表中查询。
-- 创建测试表 CREATE TABLE `test_table` ( `id` int(11) NOT NULL, `name` varchar(20) DEFAULT NULL, `desc` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), KEY `desc` (`desc`(100)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 插入测试数据 INSERT INTO `test_table` VALUES (1,'Tom','This is Tom.'),(2,'Jerry','This is Jerry.'),(3,'Lucy','This is Lucy.'),(4,'Lily','This is Lily.'); -- 使用索引查询 EXPLAIN SELECT id,`desc` FROM test_table WHERE `desc` LIKE '%Tom%';
上面的查询会使用desc索引查询,但是desc字段的长度超过了100个字符的限制,因此需要回到原表中查询,产生回表操作。
三、减少回表的方法
为了减少回表操作,可以从以下几个方面入手:
1.使用索引覆盖所有需要查询的字段
如果需要查询的字段在索引中,并且索引可以完全覆盖查询的所有字段,就不需要回到原表中查询了。
-- 创建测试表 CREATE TABLE `test_table` ( `id` int(11) NOT NULL, `name` varchar(20) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `name_age` (`name`,`age`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 插入测试数据 INSERT INTO `test_table` VALUES (1,'Tom',18),(2,'Jerry',20),(3,'Lucy',19),(4,'Lily',21); -- 使用索引查询 EXPLAIN SELECT name,age FROM test_table WHERE name='Tom';
上面的查询会使用name_age索引查询,由于查询的所有字段都在索引中,因此不需要回到原表中查询,不会产生回表操作。
2.避免使用SELECT *语句
在使用SELECT语句时,避免使用SELECT *语句,只查询需要的字段。这样可以减少回表的数据量。
-- 不使用SELECT *语句 EXPLAIN SELECT id,name FROM test_table WHERE name='Tom';
3.优化数据类型
使用长度更小的数据类型可以减少索引和数据的存储空间,从而可以减少回表操作。比如可以使用TINYINT替代INT或者使用VARCHAR替代TEXT。
4.合理使用索引
合理的索引设计可以减少回表操作,尽可能利用覆盖索引和前缀索引等技术。同时,需要注意不能为了减少回表操作而过度使用索引,导致索引失效。
5.合理的使用缓存
在MySQL中,使用缓存可以减少回表操作。比如使用Memcached来缓存查询结果,可以避免相同的查询重复回表。同时需要注意缓存的更新策略,避免缓存和实际数据的不一致。
四、总结
回表是MySQL中的一个概念,指的是在使用索引进行查询后,需要回到原表中查找记录的情况。回表操作带来了额外的IO操作,影响查询性能,因此需要尽可能减少回表的次数。为了减少回表操作,可以从优化索引、SELECT语句、数据类型、缓存等多个方面入手。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/278428.html