MySQL3-索引最佳实战

❤️ 个人主页:程序员句号
支持水滴:点赞 + 收藏⭐ + 留言+关注
订阅专栏:MySQL性能调优

MySQL性能优化专栏
1.MySQL性能优化1-MySQL底层索引结构
2.MySQL2-Explain详解
3.MySQL3-索引最佳实战
4.MySQL4-MySQL内部组件结构
5.MySQL5-事务隔离级别和锁机制
6.MySQL6-深入理解MVCC和BufferPool缓存机制

文章目录

  • 索引最佳实战(MySQL优化原则)
      • 1.全值匹配
      • 最左前缀法则
      • 不在索引列上做任何操作
      • 存储引擎不能使用索引中范围条件右边的列
      • 尽量使用覆盖索引(只访问索引的查询),减少select *语句

索引最佳实战(MySQL优化原则)

示例表:


CREATE TABLE `employees` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(24) NOT NULL DEFAULT '' COMMENT '姓名',
  `age` int(11) NOT NULL DEFAULT '0' COMMENT '年龄',
  `position` varchar(20) NOT NULL DEFAULT '' COMMENT '职位',
  `hire_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入职时间',
  PRIMARY KEY (`id`),
  KEY `idx_name_age_position` (`name`,`age`,`position`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COMMENT='员工记录表';

INSERT INTO employees(name,age,position,hire_time) VALUES('LiLei',22,'manager',NOW());
INSERT INTO employees(name,age,position,hire_time) VALUES('HanMeimei', 23,'dev',NOW());
INSERT INTO employees(name,age,position,hire_time) VALUES('Lucy',23,'dev',NOW());

1.全值匹配

EXPLAIN SELECT * FROM employees WHERE name= ‘LiLei’;

在这里插入图片描述

EXPLAIN SELECT * FROM employees WHERE name= ‘LiLei’ AND age = 22;

在这里插入图片描述

EXPLAIN SELECT * FROM employees WHERE name= ‘LiLei’ AND age = 22 AND position =‘manage
r’;

在这里插入图片描述

最左前缀法则

如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列

EXPLAIN SELECT * FROM employees WHERE name = ‘Bill’ and age = 31; 走
EXPLAIN SELECT * FROM employees WHERE age = 30 AND position = ‘dev’; 不走
EXPLAIN SELECT * FROM employees WHERE position = ‘manager’; 不走

在这里插入图片描述

不在索引列上做任何操作

在索引列上做计算、函数、自动or手动类型转换、都会导致索引失效而转向全表扫描

EXPLAIN SELECT * FROM employees WHERE name = ‘LiLei’;
EXPLAIN SELECT * FROM employees WHERE left(name,3) = ‘LiLei’;

在这里插入图片描述
给hire_time增加一个普通索引:

ALTER TABLE employees ADD INDEX idx_hire_time (hire_time) USING BTREE ;
EXPLAIN select * from employees where date(hire_time) =‘2018‐09‐30’;
在这里插入图片描述

可以优化成:
这里看到还是没有走索引,这里没走索引的原因并不是因为优化没有起作用,而是因为MySQL的优化器可能认为走索引还没有全表扫描快,因为这里我表的数据很少。但至少possible_keys有值

EXPLAIN select * from employees where hire_time >=‘2018‐09‐30 00:00:00’ and hire_time <
=‘2018‐09‐30 23:59:59’;

在这里插入图片描述
还原最初索引状态

ALTER TABLE employees DROP INDEX idx_hire_time;

存储引擎不能使用索引中范围条件右边的列

EXPLAIN SELECT * FROM employees WHERE name= ‘LiLei’ AND age = 22 AND position =‘manager’;
EXPLAIN SELECT * FROM employees WHERE name= ‘LiLei’ AND age > 22 AND position =‘manager’;

MySQL3-索引最佳实战_第1张图片
为什么范围条件右边的列不会走索引?
因为范围之后,第三个值不一定是有序的,所以只能全表扫描。而为什么不是有序的勒?因为是先按照age来排序的,age相同才会进行排序,我们参考之前的那幅图(图1)就知道了

尽量使用覆盖索引(只访问索引的查询),减少select *语句

EXPLAIN SELECT name,age FROM employees WHERE name= ‘LiLei’ AND age = 23 AND position
=‘manager’;

在这里插入图片描述

EXPLAIN SELECT * FROM employees WHERE name= ‘LiLei’ AND age = 23 AND position =‘manager’;

在这里插入图片描述

你可能感兴趣的:(MySQL性能调优,mysql,数据库,java)