mysql进阶(三)31-43

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 1.优化案例1——单表案例使用的表:-- 31讲----------------------------------------------------------create table if not exi...

1.优化案例1——单表

案例使用的表:

-- 31讲----------------------------------------------------------
create table if not exists `article`(
	`id` int(10) unsigned not null primary key auto_increment,
	`author_id` int(10) unsigned not null ,
	`category_id` int(10) unsigned not null,
	`views` int(10) unsigned not null,
	`comments` int(10) unsigned not null,
	`title` varbinary(255) not null,
	`content` text not null
);

insert into `article`(`author_id`,`category_id`,`views`,`comments`,`title`,`content` ) values 
(1,1,1,1,'1','1'),
(2,2,2,2,'2','2'),
(1,1,3,3,'3','3');

 

.

由于type是all,而且Extra是使用了using filesort,如何优化?

第一种:将category_id,comments,views设为索引;优化成range

 

第二种方式:将category_id,views设为索引,此时type变为ref,而using filesort也消失了

优化案例2——多表

-- 32讲----------------------------------------------------------
create table if not exists `class`(
	`id` int(10) unsigned not null  auto_increment,
	`card` int(10) unsigned not null,
	primary key (`id`)
);
create table if not exists `book`(
	`bookid` int(10) unsigned not null  auto_increment,
	`card` int(10) unsigned not null,
	primary key (`bookid`)
);

insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));
insert into `class`(card ) values (floor(1+(rand()*20)));

原因分析:由于在左连接中,left join 条件用于确定如何从右表中搜索行,左边表的行一定都存在,索引右边表才是我们关键的地方。

索引优化案例3:三表优化

用到的表:

create table if not exists `phone`(
	`phoneid` int(10) unsigned not null  auto_increment,
	`card` int(10) unsigned not null,
	primary key (`phoneid`)
);

insert into `phone`(card ) values (floor(1+(rand()*20)));
insert into `phone`(card ) values (floor(1+(rand()*20)));
insert into `phone`(card ) values (floor(1+(rand()*20)));
insert into `phone`(card ) values (floor(1+(rand()*20)));
insert into `phone`(card ) values (floor(1+(rand()*20)));
insert into `phone`(card ) values (floor(1+(rand()*20)));
insert into `phone`(card ) values (floor(1+(rand()*20)));

 

2.索引优化

主要讨论下面索引失效的原因:

涉及到的表结构:

CREATE TABLE `staffs`(
	id int primary key auto_increment,
	name varchar(24) not 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,'manage',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());

alter table staffs add index idx_staffs_nameAgePos(name,age,pos);

①全值匹配    :精度越高,所使用key_len越大,使用了覆盖索引;

 

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

 演示 ,没有用到索引的情况 :

③不要在索引列上做任何操作(计算、函数、(自动或者手动)类型转换),会导致索引失效而转向全表扫描。

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

也就是说在原来表的索引是(name,age,pos),在下面的查询中age>23,是索引的第二个字段,它的右边pos列就失效了

⑤尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select *

⑥mysql使用不等于(!=或者<>)的时候无法使用索引导致全表扫描;

下面是用了,覆盖索引和非覆盖索引

⑦is null,is not null也无法使用索引

⑧like通配符开头(“%abc”)mysql索引失效会变成全表扫描的操作。

最好将like的通配符放在最右边

如果like的通配符必须放在开头,可以结合覆盖索引来优化;

涉及到的表:

CREATE TABLE `tb1_user`(
	id int not null auto_increment,
	name varchar(20)  default null,
	age int(11) default null ,
	email varchar(20)  default null ,
	 primary key(`id`)
	)engine=innodb auto_increment=1 default charset=utf8;

	
insert into tb1_user(name,age,email) values ('1aa1','21','b@163.com');
insert into tb1_user(name,age,email) values ('2aa2','222','a@163.com');
insert into tb1_user(name,age,email) values ('3aa3','265','c@163.com');
insert into tb1_user(name,age,email) values ('4aa4','21','d@163.com');

建立索引:

 create index idx_nameAge on tb1_user(name,age);

⑨字符串不加单引号索引会失效

⑩少用or,用它会使索引失效。 

总结:

对于上面like案例的验证:索引是(name,age,pos)

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
存储 SQL 关系型数据库
MySQL语句详解:从基础到进阶的全面指南
MySQL语句详解:从基础到进阶的全面指南
|
4月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第三篇(MySQL性能优化)
MySQL数据库进阶第三篇(MySQL性能优化)
|
4月前
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
4月前
|
SQL 关系型数据库 MySQL
MySQL数据库进阶第五篇(锁)
MySQL数据库进阶第五篇(锁)
|
4月前
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(2)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
4月前
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(1)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
3月前
|
存储 关系型数据库 MySQL
MySQL数据库开发进阶:精通数据库表的创建与管理22
【7月更文挑战第22天】数据库的创建与删除,数据表的创建与管理
46 1
|
4月前
|
JSON 关系型数据库 MySQL
MySQL常用函数解读:从基础到进阶的全方位指南
MySQL常用函数解读:从基础到进阶的全方位指南
|
4月前
|
SQL 关系型数据库 MySQL
Python进阶第二篇(Python与MySQL数据库)
Python进阶第二篇(Python与MySQL数据库)
|
4月前
|
存储 SQL 关系型数据库
MySQL数据库进阶第四篇(视图/存储过程/触发器)
MySQL数据库进阶第四篇(视图/存储过程/触发器)