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)

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
存储 SQL 关系型数据库
MySQL语句详解:从基础到进阶的全面指南
MySQL语句详解:从基础到进阶的全面指南
|
存储 关系型数据库 MySQL
MySQL数据库进阶第三篇(MySQL性能优化)
MySQL数据库进阶第三篇(MySQL性能优化)
|
存储 关系型数据库 MySQL
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
MySQL数据库进阶第六篇(InnoDB引擎架构,事务原理,MVCC)
|
SQL 关系型数据库 MySQL
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(2)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
存储 SQL 关系型数据库
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】(1)
MySQL 进阶使用【函数、索引、视图、存储过程、存储函数、触发器】
|
存储 关系型数据库 MySQL
MySQL数据库开发进阶:精通数据库表的创建与管理22
【7月更文挑战第22天】数据库的创建与删除,数据表的创建与管理
142 1
|
JSON 关系型数据库 MySQL
MySQL常用函数解读:从基础到进阶的全方位指南
MySQL常用函数解读:从基础到进阶的全方位指南
|
SQL 关系型数据库 MySQL
Python进阶第二篇(Python与MySQL数据库)
Python进阶第二篇(Python与MySQL数据库)
|
存储 SQL 关系型数据库
MySQL数据库进阶第四篇(视图/存储过程/触发器)
MySQL数据库进阶第四篇(视图/存储过程/触发器)

推荐镜像

更多