博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mysql进阶(三)31-43
阅读量:6224 次
发布时间:2019-06-21

本文共 4462 字,大约阅读时间需要 14 分钟。

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)

你可能感兴趣的文章
MongoDB学习记录
查看>>
字符串
查看>>
如何在Ubuntu/CentOS上安装Linux内核4.0
查看>>
redis实现简单的消息队列(php)
查看>>
MySQL索引的创建、删除和查看
查看>>
汇编 ret,retf和call
查看>>
Java OCR(使用Tess4J)
查看>>
盘点selenium phantomJS使用的坑
查看>>
谈谈angular项目构建中的组织结构
查看>>
web - 实现定时弹出广告
查看>>
linux go环境搭建
查看>>
Groovy中for循环的一个奇怪现象引出的"全局变量?"
查看>>
关于表单的组件 radio select checkbox
查看>>
对chrome开发者工具的有效利用
查看>>
2011年国外最受欢迎的15个社交网站
查看>>
spring中使用logback日志组件替换log4j
查看>>
Wex5开发基础之微信支付
查看>>
JS之prototype基础篇
查看>>
如此熟悉 的梦境
查看>>
Dubbo注册到发布执行流程(原理)
查看>>