2.索引优化分析

1.常见通用的Join查询

在这里插入图片描述
建表SQL

CREATE TABLE `t_dept` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `deptName` VARCHAR(30) DEFAULT NULL,
 `address` VARCHAR(40) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 
CREATE TABLE `t_emp` (
 `id` INT(11) NOT NULL AUTO_INCREMENT,
 `name` VARCHAR(20) DEFAULT NULL,
  `age` INT(3) DEFAULT NULL,
 `deptId` INT(11) DEFAULT NULL,
 PRIMARY KEY (`id`),
 KEY `fk_dept_id` (`deptId`)
 #CONSTRAINT `fk_dept_id` FOREIGN KEY (`deptId`) REFERENCES `t_dept` (`id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
 
 
 
INSERT INTO t_dept(deptName,address) VALUES('华山','华山');
INSERT INTO t_dept(deptName,address) VALUES('丐帮','洛阳');
INSERT INTO t_dept(deptName,address) VALUES('峨眉','峨眉山');
INSERT INTO t_dept(deptName,address) VALUES('武当','武当山');
INSERT INTO t_dept(deptName,address) VALUES('明教','光明顶');
 INSERT INTO t_dept(deptName,address) VALUES('少林','少林寺');
 
INSERT INTO t_emp(NAME,age,deptId) VALUES('风清扬',90,1);
INSERT INTO t_emp(NAME,age,deptId) VALUES('岳不群',50,1);
INSERT INTO t_emp(NAME,age,deptId) VALUES('令狐冲',24,1);
 
 INSERT INTO t_emp(NAME,age,deptId) VALUES('洪七公',70,2);
INSERT INTO t_emp(NAME,age,deptId) VALUES('乔峰',35,2);
 
INSERT INTO t_emp(NAME,age,deptId) VALUES('灭绝师太',70,3);
INSERT INTO t_emp(NAME,age,deptId) VALUES('周芷若',20,3);
 
 
 
INSERT INTO t_emp(NAME,age,deptId) VALUES('张三丰',100,4);
 
INSERT INTO t_emp(NAME,age,deptId) VALUES('张无忌',25,5);
 
INSERT INTO t_emp(NAME,age,deptId) VALUES('韦小宝',18,null);
 


7种JOIN

t_emp表

select * from t_emp;

在这里插入图片描述
t_dept表
在这里插入图片描述

1.1 A、B两表共有

在这里插入图片描述

select * from t_emp inner join t_dept on t_emp.deptId = t_dept.id;

在这里插入图片描述

1.2 A、B两表共有+A的独有

在这里插入图片描述

select * from t_emp left join t_dept on t_emp.deptId = t_dept.id;

在这里插入图片描述

1.3 A、B两表共有+B的独有

在这里插入图片描述

select * from t_emp right join t_dept on t_emp.deptId = t_dept.id;

在这里插入图片描述

1.4 A的独有

在这里插入图片描述

select * from t_emp left join t_dept on t_emp.deptId = t_dept.id where t_dept.id is null;

在这里插入图片描述

1.5 B的独有

在这里插入图片描述

select * from t_emp right join t_dept on t_emp.deptId = t_dept.id where t_emp.deptId is null;

在这里插入图片描述

1.6 AB全有

在这里插入图片描述

select * from t_emp full outer join t_dept on t_emp.deptId = t_dept.id;

在这里插入图片描述

注意:MySQL不支持FULL OUTER JOIN
mysql> select * from t_emp left join t_dept on t_emp.deptId = t_dept.id
    -> union
    -> select * from t_emp right join t_dept on t_emp.deptId = t_dept.id where t_emp.deptId is null;

在这里插入图片描述

1.7 A的独有+B的独有

在这里插入图片描述

mysql> select * from t_emp left join t_dept on t_emp.deptId = t_dept.id where t_dept.id is null
    -> union
    -> select * from t_emp right join t_dept on t_emp.deptId = t_dept.id where t_emp.deptId is null;

在这里插入图片描述

2.索引简介

2.1 基本语法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.性能分析

3.1 Explain(查看执行计划)

使用EXPLAIN关键字可以模拟优化器执行SQL查询语句,从而知道MySQL是如何处理你的SQL语句的。分析你的查询语句或是表结构的性能瓶颈
使用:Explain + SQL语句
执行计划包含的信息

在这里插入图片描述

3.1.1 各字段解析

type

type显示的是访问类型,是较为重要的一个指标,结果值从最好到最坏依次是:

system > const > eq_ref > ref > range > index > ALL

system

1.表中只有一条数据
2.通过常量值匹配主键或者唯一索引

const

1.主键或者唯一索引
2.常量匹配

eq_ref

1.主键或者唯一索引扫描

ref

1.非主键或者唯一索引扫描
2.返回的结果不止一个

range

1.检索给定范围的行
2.关键字:between,< >,in

index

1.全索引扫描

ALL

1.全表扫描

possible_keys(理论上可能被用到的索引)

key(实际用到的索引)

key_len(索引中使用的字节数)

ref(显示索引的哪一列被使用了,如果可能的话,是一个常数。哪些列或常量被用于查找索引列上的值)

4.查询优化

4.1 使用索引

建表语句

 
CREATE TABLE staffs (
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR (24)  NULL DEFAULT '' COMMENT '姓名',
  age INT NOT NULL DEFAULT 0 COMMENT '年龄',
  pos VARCHAR (20) NOT NULL DEFAULT '' COMMENT '职位',
  add_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入职时间'
) CHARSET utf8 COMMENT '员工记录表' ;
 
 
INSERT INTO staffs(NAME,age,pos,add_time) VALUES('z3',22,'manager',NOW());
INSERT INTO staffs(NAME,age,pos,add_time) VALUES('July',23,'dev',NOW());
INSERT INTO staffs(NAME,age,pos,add_time) VALUES('2000',23,'dev',NOW());
INSERT INTO staffs(NAME,age,pos,add_time) VALUES(null,23,'dev',NOW());
SELECT * FROM staffs;
 
ALTER TABLE staffs ADD INDEX idx_staffs_nameAgePos(name, age, pos);


索引失效

1.全值匹配我最爱

索引  idx_staffs_nameAgePos 建立索引时 以 name , age ,pos 的顺序建立的。全值匹配表示 按顺序匹配的
EXPLAIN SELECT * FROM staffs WHERE NAME = 'July';
EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND age = 25;
EXPLAIN SELECT * FROM staffs WHERE NAME = 'July' AND age = 25 AND pos = 'dev';

在这里插入图片描述
2.最佳左前缀法则
如果索引了多列,要遵守最左前缀法则。指的是查询从索引的最左前列开始并且不跳过索引中的列

 and 忽略左右关系。既即使没有没有按顺序 由于优化器的存在,会自动优化。
经过试验结论  建立了 idx_nameAge 索引  id 为主键
    1.当使用覆盖索引的方式时,(select name/age/id from staffs where age=10 (后面没有其他没有索引的字段条件)),即使不是以 name 开头,也会使用 idx_nameAge 索引。
    既 select 后的字段 有索引,where 后的字段也有索引,则无关执行顺序。
    2.除开上述条件 才满足最左前缀法则。
 
EXPLAIN SELECT * FROM staffs WHERE age = 25 AND pos = 'dev';
 
EXPLAIN SELECT * FROM staffs WHERE pos = 'dev';

在这里插入图片描述
3.不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描
在这里插入图片描述
4.存储引擎不能使用索引中范围条件右边的列
范围 若有索引则能使用到索引,范围条件右边的索引会失效(范围条件右边与范围条件使用的同一个组合索引,右边的才会失效。若是不同索引则不会失效)
在这里插入图片描述
5.尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *
在这里插入图片描述
6.mysql 在使用不等于(!= 或者<>)的时候无法使用索引会导致全表扫描
索引 idx_nameAgeJob
idx_name
使用 != 和 <> 的字段索引失效( != 针对数值类型。 <> 针对字符类型
前提 where and 后的字段在混合索引中的位置比比当前字段靠后 where age != 10 and name=‘xxx’ ,这种情况下,mysql自动优化,将 name=‘xxx’ 放在 age !=10 之前,name 依然能使用索引。只是 age 的索引失效)
在这里插入图片描述
7.is not null 也无法使用索引,但是is null是可以使用索引的
在这里插入图片描述
8.like以通配符开头(’%abc…’)mysql索引失效会变成全表扫描的操作
解决此问题应该用覆盖索引。

9.字符串不加单引号索引失效
在这里插入图片描述
10.少用or,用它来连接时会索引失效
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL的`EXPLAIN`语句可以帮助我们分析查询语句的执行计划,从而优化查询性能。下面是一些常见的优化指标和相关的解释: 1. `type`列:表示访问数据的方式,常见的取值有`ALL`、`index`、`range`、`ref`、`eq_ref`、`const`等。一般来说,访问数据的方式越好,性能越高。 2. `key`列:表示使用的索引。如果该列为NULL,则表示没有使用索引索引的选择要尽量满足查询条件,并且覆盖需要返回的数据列。 3. `rows`列:表示MySQL估计需要扫描的行数。行数越少,性能越好。 4. `Extra`列:额外的信息,常见取值有`Using where`、`Using index`、`Using temporary`、`Using filesort`等。这些信息可以帮助我们判断是否存在潜在的性能问题。 根据这些指标,我们可以进行索引优化,以下是一些常见的优化策略: 1. 确保表上有适当的索引。通过分析查询语句的WHERE条件和JOIN条件,选择合适的索引。可以使用`CREATE INDEX`语句来创建索引。 2. 尽量避免全表扫描(即type为`ALL`)。可以通过添加适当的索引优化查询语句或者调整表结构来避免全表扫描。 3. 避免使用临时表(即`Using temporary`)。可以通过优化查询语句,避免使用`GROUP BY`、`DISTINCT`、`UNION`等操作,从而避免使用临时表。 4. 避免使用文件排序(即`Using filesort`)。可以通过添加适当的索引、调整查询语句或者调整排序方式来避免文件排序。 5. 注意使用索引覆盖。索引覆盖是指查询时只使用索引而不需要访问表数据,可以通过合理选择索引和查询列来实现。 以上是一些常见的MySQL索引优化方法,具体的优化策略需要根据具体的查询语句和数据情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值