创建测试表,添加测试数据

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `manager_id` int(11) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idex_name_age_managerid` (`name`,`age`,`manager_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES ('205', null, '24', '102','henan');
INSERT INTO `users` VALUES ('206', null, '25', '102','shandong');
INSERT INTO `users` VALUES ('101', 'jack', '35', null,'beijing');
INSERT INTO `users` VALUES ('102', 'tom', '30', '101','shanghai');
INSERT INTO `users` VALUES ('201', 'xiaoli', '23', '102','shanxi');
INSERT INTO `users` VALUES ('203', 'xiaoliu', '22', '102','guangzhou');

根据组合索引 idex_name_age_managerid (`name`,`age`,`manager_id`) 测试不同场景下的sql执行计划

1)EXPLAIN SELECT * FROM `users` WHERE name = 'tom' and age = 30 and manager_id = 101;

 2)EXPLAIN SELECT * FROM `users` WHERE name = 'tom';

3)EXPLAIN SELECT * FROM `users` WHERE age = 30;

4)EXPLAIN SELECT * FROM `users` WHERE manager_id = 101;

5)EXPLAIN SELECT * FROM `users` WHERE name = 'tom' and age = 30;

6)EXPLAIN SELECT * FROM `users` WHERE name = 'tom' and manager_id = 101;

7)EXPLAIN SELECT * FROM `users` WHERE age = 30 and manager_id = 101;

8)EXPLAIN SELECT * FROM `users` WHERE age = 30 AND name = 'tom';

9)EXPLAIN SELECT * FROM `users` WHERE manager_id= 101 AND name = 'tom';

 

结论总结:

1、由以上执行计划可以看出,第3、4、7个执行计划没有命中索引,所以,只要是以含有 name条件的sql语句都命中了索引(遵循左前缀原则);

2、第8、9个sql虽然没有以name开头,但是也命中了索引,说明 mysql的查询优化器会帮你优化成索引可以识别的形式。

3、根据执行计划分析,命中索引的sql第6、9个查询效率是比较低的,filtered只有16.67,所以:

组合索引 idex_name_age_managerid (`name`,`age`,`manager_id`)   sql 执行为了提高执行效率,where 条件字段顺序应该遵循以下组合

name

name,age

name,age,manager_id

注:

filtered = (查询结果条数/rows),例如第9个查询 filtered = 1/6 = 16.67

Logo

更多推荐