PHP_MySQL优化(1)
一、mysql优化概述
前面我们讲页面静态化,memcache是通过减少对mysql 操作来提升访问速度,但是一个网站总是要操作数据库,我们如何提升对mysql的操作速度。
① 存储层:数据表”存储引擎”选取、字段类型选取、逆范式(3范式)
④ sql语句层:结果一样的情况下,要选择效率高、速度快、节省资源的sql语句执行
二、存储引擎的选择
1、存储引擎介绍
(1)什么是存储引擎?
数据存储在不同的格式里边,该格式体现的特性也是不一样的。例如innodb存储引擎的特性有支持事务、支持行级锁,mysiam支持的特性有压缩机制等。
MySQL中的数据是通过各种不同的技术(格式)存储在文件(或者内存)中的。技术和本身的特性就称为"存储引擎"。
(2)存储引擎的理解:
现实生活中,楼房、平房就是具体存储人的存储引擎,楼房、平房有自己独特的技术特性
(3)存储引擎所处的位置:
存储引擎,处于MySql服务器的最底层,直接存储数据,导致上层的操作,依赖于存储引擎的选择。
客户端-》网络连接层-》业务逻辑层(编译,优化,执行SQL)-》存储引擎层
查看当前mysql支持的存储引擎列表:show engines
(4)常用存储引擎:
2、innodb存储引擎
>=5.5 版本中默认的存储引擎,MySql推荐使用的存储引擎。提供事务,行级锁定,存储引擎。
(1)存储格式:
innodb存储引擎 每个数据表有单独的“结构文件” *.frm
数据,索引集中存储,存储于同一个表空间文件中ibdata1。
ibdata1就是InnoDB表的共享存储空间,默认innodb所有表的数据都在一个ibdata1里。
create table t1(id int,name varchar(32)) engine innodb charset utf8;
默认,所有的 innodb表的数据和索引在同一个表空间文件中,
show variables like ‘innodb_file_per_table%’
set global innodb_file_per_table=1;
系统配置参数innodb_file_per_table后期无论发生任何变化,t2都有自己独立的“数据/索引”文件。
注意:innodb数据表不能直接进行文件的复制/粘贴进行备份还原,可以使用如下指令:
> mysqldump -uroot -p密码 数据库名字 > f:/文件名称.sql [备份]
> mysql -uroot -p密码 数据库 < f:/文件名称.sql [还原]
(2)数据是按照主键顺序存储。
该innodb数据表,数据的写入顺序 与 存储的顺序不一致,需要按照主键的顺序把记录摆放到对应的位置上去,速度比Myisam的要稍慢。
id int primary key auto_increment,
insert into t3 values(223,'刘备'),(12,'张飞'),(162,'张聊'),(1892,'网飞');
(3)并发处理:
行级锁定(row-level locking),实现了行级锁定,在一定情况下,可以选择行级锁来提升并发性,也支持表级锁定,innodb根据操作选择。
当客户端操作表(记录)时,为了保证操作的隔离性(多个客户端操作不能相互影响),通过加锁来处理。
读锁:读操作时增加的锁,也叫共享锁,S-lock。特征是所有人都只可以读,只有释放锁之后才可以写。
写锁:写操作时增加的锁,也叫独占锁或排他锁,X-lock。特征,只有锁表的客户可以操作(读写)这个表,其他客户读都不能读。
表级锁:开销小,加锁快,发生锁冲突的概率最高,并发度最低。myisam和innodb都支持。
行级锁:开销大,加锁慢,发生锁冲突的概率最低,并发度也最高。innodb支持
3、MyISAM存储引擎
(ISAM——索引顺序访问方法)是Indexed Sequential Access Method(索引顺序存取方法)的缩写
它是一种索引机制,用于高效访问文件中的数据行,擅长与处理高速读与写。
(1)存储方式:
create table t4(id int,name varchar(32)) engine myisam charset utf8;
mysiam存储引擎数据表,每个数据表都有三个文件*.frm(结构文件) *.MYD(数据文件) *.MYI(索引文件)
(2)数据的存储顺序为插入顺序。
id int primary key auto_increment,
insert into t5 values(2223,'刘备'),(12,'张飞'),(162,'张聊'),(1892,'网飞');
数据写入时候,没有按照主键id值给予排序存储,该特点导致数据写入的速度非常快。
(3)并发性
mysiam的并发性较比innodb要稍逊色(mysiam不支持事务)
如果表对事务的要求不高,同时是以查询和添加为主,我们考虑使用MyISAM存储引擎,比如bbs中的发帖表,回复表。
对事务要求高,保存的数据都是重要数据,我们建议使用INNODB,比如订单表,库存表,商品表,账号表等等。
4、memory
create table t6(id int,name varchar(32)) engine memory charset utf8;
三、查找需要优化语句
1、慢查询日志
是一种mysql提供的日志,记录所有执行时间超过某个时间界限的sql的语句。这个时间界限,我们可以指定。在mysql中默认没有开启慢查询,即使开启了,只会记录执行的sql语句超过10秒的语句。
方式一、临时启动慢查询记录日志
(1){mysql程序所在的目录}>bin/mysqld.exe --safe-mode --slow-query-log
>bin/mysqld.exe --safe-mode --slow-query-log
通过慢查询日志定位执行效率较低的SQL语句。慢查询日志记录了所有执行时间超过long_query_time所设置的SQL语句。
(2)在默认情况下,慢查询日志是存储到data目录下面的。根据配置文件里面的配置,找到data的存储路径。
show variables like ‘long_query_time’;
修改慢查询日志时间:set long_query_time=0.5;
benchmark(count,expr)函数可以测试执行count次expr操作需要的时间。
select benchmark(10000,90000000*4)
添加索引之后:alter table emp add index(empno)
结论:创建完索引后,索引文件会变大,添加索引会明显的提高查询速度。
方式二:通过修改配置文件,添加如下语句
log-slow-queries="d:/slow-log"
慢查询日志文件存储的路径,当前是把慢查询日志存储到d:盘下面,文件名为slow-log
指定慢查询的时间,默认是10秒,我们自定义成1或0.05秒,也就是说当一个sql语句的执行速度超过1秒时,会把该语句添加到慢查询日志里面,
2、精确记录查询时间
profile记录每次执行的sql语句的具体时间,精确时间到小数点8位
四、索引讲解
1、索引的基本介绍
利用关键字,就是记录的部分数据(某个字段,某些字段,某个字段的一部分),建立与记录位置的对应关系,就是索引。
2、索引的类型:
无论任何类型,都是通过建立关键字与位置的对应的关系来实现的。
关键字:记录的部分数据(某个字段,某些字段,某个字段的一部分)
主键索引:要求关键字不能重复,也不能为NULL。同时增加主键约束。
全文索引:关键字的来源不是所有字段的数据,而是从字段中提取的特别关键词。
关键词的来源:可以是某个字段,也可以是某些字段(复合索引)。如果一个索引通过在多个字段上提取的关键字,称之为复合索引。
比如:alter table emp add index (field1,field2)
3、索引管理语法
(1)创建索引:
注意:索引可以起名字,但是主索引不能起名字,因为一个表仅仅可以有一个主键索引,其他索引可以出现多个。名字可以省略,mysql会默认生成,通常使用字段名来充当。
第一点:如果表中存在数据,数据符合唯一或主键约束才可能创建成功。
第二点:auto_increment属性,依赖于一个KEY(主键或唯一)。
(2)删除索引
删除主键索引:alter table table_name drop primary key
主键索引的删除,如果没有auto_increment 属性则使用 alter table 表名 drop primary key
如果在删除主键索引时,该字段中有auto_increment则先去掉该属性再删除。
alter table 表名 modify id int unsigned not null comment '主键'
如有主键中有auto_incrments属性时,删除主键索引,则报如图提示。
alter table index1 modify id int unsigned;
alter table 表名 drop index 索引的名称;
如果没有指定索引名,则可以通过查看索引的方法得到索引名(一般依赖于索引字段的名字)
(3)查看索引
(4)创建索引注意事项:
select * from emp where empno = 1
第二:唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件
select * from emp where sex = '男‘
select * from emp where logincount = 1
五、执行计划
主要用于分析sql语句的执行情况(并不执行sql语句)得到sql语句是否使用了索引,使用了哪些索引。
语法:explain sql语句\G 或 desc sql语句\G
六、索引的数据结构
1、myisam的存储引擎索引结构:
在查找数据时,查找到索引后,根据索引节点中记录的物理地址,查找到具体的数据内容。
2、innodb的存储引擎的索引结构
innodb的主键索引文件上 直接存放该行数据,称为聚簇索引,非主索引指向对主键的引用(非主键索引的节点存储是主键的id)
比如要通过nam创建的索引,查询name=’采臣’的,先根据name建立的索引,找出该条记录的主键id,再根据主键的id通过主键索引找出该条记录。
innodb的主索引文件上 直接存放该行数据,称为聚簇索引,非主索引指向对主键的引用
myisam中, 主索引和非主索引,都指向物理行(磁盘位置).
3: 如果没有unique,则系统生成一个内部的rowid做主键.
4: 像innodb中,主键的索引结构中,既存储了主键值,又存储了行数据,这种结构称为”聚簇索引”
优势: 根据主键查询条目比较少时,不用回行(数据就在主键节点下)
劣势: 如果碰到不规则数据插入时,造成频繁的页分裂(索引的节点移动).
七、索引覆盖
索引覆盖是指:如果查询的列恰好是索引的一部分,那么查询只需要在索引区上进行,不需要到数据区再找数据,这种查询速度非常快,称为“索引覆盖”
索引覆盖就是,我要在书里 查找一个内容,由于目录写的很详细,我在目录中就获取到了,不需要再翻到该页查看。
在user表里面,给name字段添加索引,查询name,就用到了索引覆盖。
索引使用的场合如下,在没有条件时,直接查询建立索引的字段时,
案例2:比如给id和name 建立了复合索引,使用name作为条件查询。
Select id, name, height,gender from student where name=’XXX’;
Alter table student add index (name);
Alter table student add index (name, id, height, gender, class_id);
select name, id, height, gender, class_id from student
八、索引的使用原则
1、列独立
只有参与条件表达式的字段独立在关系运算符的一侧,该字段才可能使用到索引。
“独立的列”是指索引列不能是表达式的一部分,也不能是函数的参数。
2、like查询
在使用like(模糊匹配)的时候,在左边没有通配符的情况下,才可以使用索引。
注意,如果select的字段正好就是索引,那么会用到索引即索引覆盖。
如果该表改为innodb引擎,因为非主键索引中存储的是id,select的字段是id因此用到了索引覆盖。
比如如下把表改成了 innodb的引擎,对name建立了索引,如下查询,就用到了索引覆盖。
3、OR运算都具有索引
如果出现OR(或者)运算,要求所有参与运算的字段都存在索引,才会使用到索引。
4、复合索引使用
对于创建的多列(复合)索引,只要查询条件使用了最左边的列,索引一般就会被使用。
注意:在多列索引里面,如果有多个查询条件,要想查询效率比较高,比如如下建立的索引,
4、mysql 智能选择
如果mysql认为,全表扫描不会慢于使用索引,则mysql会选择放弃索引,直接使用全表扫描。一般当取出的数据量超过表中数据的20%,优化器就不会使用索引,而是全表扫描。
5、优化group by语句。
根据classid分组,自动根据classid进行 了排序,
select classid,sum(age) from user group by classid;
如果不想根据classid排序,则可以在后面使用order by nulll
select classid,sum(age) from user group by classid order by null;
九、mysql中锁机制
1、应用场合:
2、mysql里面的锁的几种形式
当客户端操作表(记录)时,为了保证操作的隔离性(多个客户端操作不能相互影响),通过加锁来处理。
读锁:读操作时增加的锁,也叫共享锁,S-lock。特征是所有人都只可以读,只有释放锁之后才可以写。
写锁:写操作时增加的锁,也叫独占锁或排他锁,X-lock。特征,只有锁表的客户可以操作(读写)这个表,其他客户读都不能读。
行级锁:开销大,加锁慢,发生锁冲突的概率最低,并发度也最高。
3、表锁的演示,
id int primary key auto_increment,
name varchar(32) not null default '',
age tinyint unsigned not null default 0,
email varchar(32) not null default '',
classid int not null default 1
insert into user values(null,'xiaogang',12,'gang@sohu.com',4),
(null,'xiaohong',13,'hong@sohu.com',2),
(null,'xiaolong',31,'long@sohu.com',2),
(null,'xiaofeng',22,'feng@sohu.com',3),
(null,'xiaogui',42,'gui@sohu.com',3);
添加锁的语法: lock table table_name1 read|write,table_name2 read|write
语法:lock table_name read|write;
注意:添加读锁后,自己和其他的进程(用户)只能对该表查询操作,自己也不能执行修改操作。
注意:添加表的锁定后,针对锁表的用户,只能操作锁定的表,不能操作没有锁定的表。
查看另外的一个用户,是否可以操作该表,其他的用户,读都不能读,
4、行锁的演示
innodb存储引擎是通过给索引上的索引项加锁来实现的,这就意味着:只有通过索引条件(主键)检索数据,innodb才会使用行级锁,否则,innodb使用表锁。
5、通过php代码来实现锁机制。
在apache里面有一个bin目录 下面有一个ab.exe工具,该工具可以模拟多个并发测试。
查看表里面的id的值,我们执行了代码50次,应该id的值是150才对,则说明我们请求的50个并发,有几个并发是同时执行的。
使用mysql里面锁机制缺点:就是阻塞,假如有一张goods表,goods表里面有一个库存的字段,当前下订单时,如果锁定了goods表,还能执行查询goods表吗?
会阻塞拖慢整个网站的速度,一但锁定goods表(添加写锁,要更改库存),则其他进程就无法查询goods表。
<?php
error_reporting(0);
$conn = mysql_connect('localhost','root','root');
mysql_query('use demo');
mysql_query('set names utf8');
//打开该文件
$fh = fopen('./lock.txt','w');
//添加锁
flock($fh,LOCK_EX );//添加锁
//mysql_query('lock table a write');//添加写锁
//取出id的值
$res = mysql_query('select id from a');
$row = mysql_fetch_assoc($res);
$id = $row['id'];
//执行该id+1运算
$id = $id+1;
//执行结果,再写入数据库
mysql_query("update a set id = $id");
//mysql_query('unlock tables');
flock($fh,LOCK_UN );
//释放锁
PHP_MySQL优化(1)相关推荐
- 系统遇到并发瓶颈时的优化方向
1. 设计高质量代码优化Map 使用读写锁,读写锁 读多写少(存储用户连接信息) map不要太大. 2. 突破系统瓶颈 优化连接数 linux下的系统最大连接数 3. 降低对Cpu资源的使用 降低io ...
- SVN优化(一) SVN忽略maven项目的target
SVN优化(一) SVN忽略maven项目的target 一 eclipse刚开始导入的项目: 二 解决办法 方式一: 在项目代码路径,如: F:\xyx\sl 鼠标右键,"Tortoi ...
- 如何定位并优化慢查询Sql
根据慢日志定位慢查询SQL. 查询慢日志相关变量,并进行设置: 主要关注下述三个变量: long_query_time.show_query_log_file.show_query_log 慢查询sq ...
- kali2020进入单模式_蚂蚁集团技术专家山丘:性能优化的常见模式及趋势
陈显铭(山丘) 读完需要 6分钟 速读仅需 2 分钟 陈显铭,花名山丘,就职于蚂蚁集团,对分布式应用架构.服务化.性能优化等有深入的理解.参与支付宝支付链路核心系统,设计.调优应用系统关键能力, 高效 ...
- 各种优化算法公式快速回忆优化器-深度学习
本文是Deep Learning 之 最优化方法系列文章的RMSProp方法.主要参考Deep Learning 一书. 整个优化系列文章列表: Deep Learning 之 最优化方法 Deep ...
- Pytorch实现MNIST(附SGD、Adam、AdaBound不同优化器下的训练比较) adabound实现
学习工具最快的方法就是在使用的过程中学习,也就是在工作中(解决实际问题中)学习.文章结尾处附完整代码. 一.数据准备 在Pytorch中提供了MNIST的数据,因此我们只需要使用Pytorch提 ...
- 从 SGD 到 Adam —— 深度学习优化算法概览 各种优化器 重点
20210701 https://blog.51cto.com/u_15064630/2571266 [机器学习基础]优化算法详解 详细 https://blog.csdn.net/u01338501 ...
- 梯度优化算法Adam
最近读一个代码发现用了一个梯度更新方法, 刚开始还以为是什么奇奇怪怪的梯度下降法, 最后分析一下是用一阶梯度及其二次幂做的梯度更新.网上搜了一下, 果然就是称为Adam的梯度更新算法, 全称是:自适应 ...
- pytorch 优化器 机器学习 调参
torch.optim 如何使用optimizer 构建 为每个参数单独设置选项 进行单次优化 optimizer.step() optimizer.step(closure) 算法 如何调整学习率 ...
最新文章
- 爬虫python代码-Python爬虫入门(01) -- 10行代码实现一个爬虫
- MATLAB 中怎么求图像在水平方向和垂直方向的像素和,用图表示
- Java并发编程--ReentrantReadWriteLock
- mysql考试选择题
- ai/ml_您本周应阅读的有趣的AI / ML文章(8月9日)
- Hive的使用之脚本文件
- 荣耀发布了全球首款 4800 万像素手机,并推出 YOYO 智能音箱...
- 试戴系统完全开放—zoomla!逐浪cms在后4.6时代的又一个亮点
- IBatis.net动态SQL语句(六)
- 35-BigDecimal详解
- MyBatis Generator.xml详解
- [20180801]insert导致死锁.txt
- Bolg-First
- ESET NOD32 最新更新有效的升级ID用户名和密码
- Cesium视频教程
- 盘点HTML页面跳转的5种方法
- DS homework-队列
- 项目管理工具dhtmlxGantt甘特图入门教程(八):数据加载(二)
- 由NPLM到Word2vec
- 在武汉火车站转车需要出现吗_武汉火车站可以在站内换乘哪些站 武汉地铁6号线和1号线/13号线换乘...
热门文章
- Python爬虫实战(1) | 爬取豆瓣网排名前250的电影(下)
- 富士通半导体携手奇瑞汽车
- 再见python,你好Java
- httplib下载http链接的DOC文档
- ShaderJoy —— 新人所不知道的 GLSL 函数坑
- 大学本科生、研究生和博士生的本质区别
- 【GCC编译优化系列】GCC链接失败的错误提示 undefined reference to ‘xxx‘ 可能还有一种情况你没注意到?
- php文件怎么转换jpg文件怎么打开方式,heic文件如何打开 heic格式转换JPG方法【步骤教程】...
- php开发微信公众号,接收粉丝过来的小视频
- Aspose.Words 开发资料整理