如何处理PHP和MYSQL的并发以及优化
sql优化,数据缓存和页面静态化
首先各种优化程序逻辑优化数据库优化硬件横向扩展
数据hash、服务器提升性能、表hash、出钱找oraclec出解决方案
页面静态化:
Php页面静态化有两种,第一,php模板,比如:smarty。第二,url伪静态,通过urlrewrite实现这种做法可以提高网站的排名和收索
像一些管理性质的网站,比如:新闻发布系统、CMS等,使用php模板静态化。一般的网站伪静态就可以了
数据缓存:
php程序常规的获取数据的流程是:
1.用户向php程序发送请求
2.php请求从数据库中取出数据
3.发送给用户
但是当网站的访问量非常大的时候数据库往往成为制约系统性能的瓶颈,为了减轻大规模请求对数据库造成的压力,简单的方法可以采用数据缓存来减轻数据库的压力,下面就简单的介绍一下常规的数据缓存方法:
具体的步骤:
1.用户请求
2.判断缓存是否存在或者是否过期
3.如果缓存不存在或者缓存已经过期,从数据库中读出数据;如果没有过期,读取缓存
4.发送给用户
文件方式缓存数据示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//数据库连接省略
$cache_dir='cache';//缓存文件夹
$cache_time='60';//缓存时间
$sql='select*fromtest';
$cache_file=$cache_dir.'/'.md5($sql);//以sql语句的md5值作为缓存文件名(当然也可以用其他方式)
//如果缓存存在并且缓存未过期
if(file_exists($cache_file)&&time()-filemtime($cache_file)<$cache_time){
$data=unserialize(file_get_contents($cache_file));//读取缓存后反序列化
}else{
//读取数据库
$query=mysql_query($sql);
//省略...
$data="数据库中读取...";
//把读取的数据序列化后写入缓存
file_put_contents($cache_file,serialize($data));
}
//呵呵,这里就是想要的数据
print_r($data);
Memcache缓存数据示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//先要安装memcache服务端和memcachephp扩展
$memcache=newMemcache;
$memcache->connect('localhost',11211)ordie("Couldnotconnect");
$cache_time='60';//缓存时间
$sql='select*fromtest';
$key=md5($sql);
if(!$memcache->get($key)){//如果缓存不存在
//读取数据库
$query=mysql_query($sql);
//省略...
$data="数据库中读取...";
//把读取的数据写入缓存
$memcache->set($key,$data,0,$cache_time);
}else{//缓存存在
$data=$memcache->get($key);//读取缓存
}
print_r($data);
sql优化:
根据情况选择最优的引擎是innodb还是myisam,比如mysql有很多第三方开源优化方案Facebook在mysql的第三方插件使用上有很多做法。Pdo
innodb还是myisam
常用于读取的数据表,sql引擎选择myisam
常用于插入、修改、删除等操作的数据表,sql引擎选择innodb
1.查询的模糊匹配
尽量避免在一个复杂查询里面使用LIKE'%parm1%'——红色标识位置的百分号会导致相关列的索引无法使用,最好不要用.
解决办法:
其实只需要对该脚本略做改进,查询速度便会提高近百倍。改进方法如下:
a、修改前台程序——把查询条件的供应商名称一栏由原来的文本输入改为下拉列表,用户模糊输入供应商名称时,直接在前台就帮忙定位到具体的供应商,这样在调用后台程序时,这列就可以直接用等于来关联了。
b、直接修改后台——根据输入条件,先查出符合条件的供应商,并把相关记录保存在一个临时表里头,然后再用临时表去做复杂关联
2.索引问题
在做性能跟踪分析过程中,经常发现有不少后台程序的性能问题是因为缺少合适索引造成的,有些表甚至一个索引都没有。这种情况往往都是因为在设计表时,没去定义索引,而开发初期,由于表记录很少,索引创建与否,可能对性能没啥影响,开发人员因此也未多加重视。然一旦程序发布到生产环境,随着时间的推移,表记录越来越多
这时缺少索引,对性能的影响便会越来越大了。
这个问题需要数据库设计人员和开发人员共同关注
法则:不要在建立的索引的数据列上进行下列操作:
*避免对索引字段进行计算操作
*避免在索引字段上使用not,<>,!=
*避免在索引列上使用ISNULL和ISNOTNULL
*避免在索引列上出现数据类型转换
*避免在索引字段上使用函数
*避免建立索引的列中使用空值。
3.复杂操作
部分UPDATE、SELECT语句写得很复杂(经常嵌套多级子查询)——可以考虑适当拆成几步,先生成一些临时数据表,再进行关联操作
4.update
同一个表的修改在一个过程里出现好几十次,如:
updatetable1
setcol1=...
wherecol2=...;
updatetable1
setcol1=...
wherecol2=...
......
象这类脚本其实可以很简单就整合在一个UPDATE语句来完成(前些时候在协助xxx项目做性能问题分析时就发现存在这种情况)
5.在可以使用UNIONALL的语句里,使用了UNION
UNION因为会将各查询子集的记录做比较,故比起UNIONALL,通常速度都会慢上许多。一般来说,如果使用UNIONALL能满足要求的话,务必使用UNIONALL。还有一种情况大家可能会忽略掉,就是虽然要求几个子集的并集需要过滤掉重复记录,但由于脚本的特殊性,不可能存在重复记录,这时便应该使用UNIONALL,如xx模块的某个查询程序就曾经存在这种情况,见,由于语句的特殊性,在这个脚本中几个子集的记录绝对不可能重复,故可以改用UNIONALL)
6.在WHERE语句中,尽量避免对索引字段进行计算操作
这个常识相信绝大部分开发人员都应该知道,但仍有不少人这么使用,我想其中一个最主要的原因可能是为了编写写简单而损害了性能,那就不可取了
9月份在对XX系统做性能分析时发现,有大量的后台程序存在类似用法,如:
......
wheretrunc(create_date)=trunc(:date1)
虽然已对create_date字段建了索引,但由于加了TRUNC,使得索引无法用上。此处正确的写法应该是
wherecreate_date>=trunc(:date1)andcreate_date<PRE>
或者是
wherecreate_datebetweentrunc(:date1)andtrunc(:date1)+1-1/(24*60*60)
注意:因between的范围是个闭区间(greaterthanorequaltolowvalueandlessthanorequaltohighvalue.),
故严格意义上应该再减去一个趋于0的小数,这里暂且设置成减去1秒(1/(24*60*60)),如果不要求这么精确的话,可以略掉这步。
7.对Where语句的法则
7.1避免在WHERE子句中使用in,notin,or或者having。
可以使用exist和notexist代替in和notin。
可以使用表链接代替exist。Having可以用where代替,如果无法代替可以分两步处理。
例子
SELECT*FROMORDERSWHERECUSTOMER_NAMENOTIN
(SELECTCUSTOMER_NAMEFROMCUSTOMER)
优化
SELECT*FROMORDERSWHERECUSTOMER_NAMEnotexist
(SELECTCUSTOMER_NAMEFROMCUSTOMER)
7.2不要以字符格式声明数字,要以数字格式声明字符值。(日期同样)否则会使索引无效,产生全表扫描。
例子使用:
SELECTemp.ename,emp.jobFROMempWHEREemp.empno=7369;
不要使用:SELECTemp.ename,emp.jobFROMempWHEREemp.empno=‘7369’
8.对Select语句的法则
在应用程序、包和过程中限制使用select*fromtable这种方式。看下面例子
使用SELECTempno,ename,categoryFROMempWHEREempno='7369‘
而不要使用SELECT*FROMempWHEREempno='7369'
9.排序
避免使用耗费资源的操作,带有DISTINCT,UNION,MINUS,INTERSECT,ORDERBY的SQL语句会启动SQL引擎执行,耗费资源的排序(SORT)功能.DISTINCT需要一次排序操作,而其他的至少需要执行两次排序
10.临时表
慎重使用临时表可以极大的提高系统性能
新浪微博对大数据量处理还用到了热点数据处理方法类似于热点数据缓存
淘宝在大型活动时为了保证不宕机会采用降级服务
这些都是我知道的大并发处理方法
如何处理PHP和MYSQL的并发以及优化的更多相关文章
- Tomcat + Mysql高并发配置优化
1.Tomcat优化配置 (1)更改Tomcat的catalina.bat 将java变成server模式,增大jvm的内存,在文件开始位置增加 setJAVA_OPTS=-server -Xms10 ...
- spark jdbc(mysql) 读取并发度优化
转自:https://blog.csdn.net/lsshlsw/article/details/49789373 很多人在spark中使用默认提供的jdbc方法时,在数据库数据较大时经常发现任务 h ...
- 性能调优之MYSQL高并发优化
性能调优之MYSQL高并发优化 一.数据库结构的设计 如果不能设计一个合理的数据库模型,不仅会增加客户端和服务器段程序的编程和维护的难度,而且将会影响系统实际运行的性能.所以,在一个系统开始实施之 ...
- 高并发大流量专题---10、MySQL数据库层的优化
高并发大流量专题---10.MySQL数据库层的优化 一.总结 一句话总结: mysql先考虑做分布式缓存,过了缓存后就做mysql数据库层面的优化 1.mysql数据库层的优化的前面一层是什么? 数 ...
- [MySQL Reference Manual] 8 优化
8.优化 8.优化 8.1 优化概述 8.2 优化SQL语句 8.2.1 优化SELECT语句 8.2.1.1 SELECT语句的速度 8.2.1.2 WHERE子句优化 8.2.1.3 Range优 ...
- 第 8 章 MySQL 数据库 Query 的优化
前言: 在之前“影响 MySQL 应用系统性能的相关因素”一章中我们就已经分析过了Query语句对数据库性能的影响非常大,所以本章将专门针对 MySQL 的 Query 语句的优化进行相应的分析. ...
- MySQL 数据库 Query 的优化
理解MySQL的Query Optimizer MySQL Optimizer是一个专门负责优化SELECT 语句的优化器模块,它主要的功能就是通过计算分析系统中收集的各种统计信息,为客户端请求的Qu ...
- MySQL性能调优与架构设计——第8章 MySQL数据库Query的优化
第8章 MySQL数据库Query的优化 前言: 在之前“影响 MySQL 应用系统性能的相关因素”一章中我们就已经分析过了Query语句对数据库性能的影响非常大,所以本章将专门针对 MySQL 的 ...
- 大型php网站性能和并发访问优化方案(转载自php中文网)
网站性能优化对于大型网站来说非常重要,一个网站的访问打开速度影响着用户体验度,网站访问速度慢会造成高跳出率,小网站很好解决,那对于大型网站由于栏目多,图片和图像都比较庞大,那该怎 ...
随机推荐
- ThinkPHP 模型(Model)命名规范
一个小问题搞了好久:如果数据库的表名中有下划线,那么在用thinkphp做自动完成时注意Model类的命名要变成驼峰法,文件名和类名都要变.( 另外注意:只有使用create方法创建数据时才能调用到自 ...
- 请求webservice接口的某方法数据
NSURL *url = [NSURL URLWithString:@"http://xxx.xxx.com/xxx/xxxxWS?wsdl"]; NSString *soapMs ...
- HDU 5813 Elegant Construction(优雅建造)
HDU 5813 Elegant Construction(优雅建造) Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65 ...
- 获取Token不完整问题
有时会遇到获取Token只能获取一半的问题,明明有两个Cookie,但只获取到一个,这个是因为301重定向跳转设置问题,设置为True就可以获取到完整的Token了. myHttpWebRequest ...
- Scrum Meeting---Four(2015-10-28)
今日已完成任务和明日要做的任务 姓名 今日已完成任务 今日时间 明日计划完成任务 估计用时 董元财 今日我完成了数据库表的设计以及创建 3h 进行Java Web工程的编写 4h 胡亚坤 用户之间的通 ...
- hdu 1058 Humble Numbers
这题应该是用dp来做的吧,但一时不想思考了,写了个很暴力的,类似模拟打表,然后排序即可,要注意的是输出的格式,在这里wa了一发,看了别人的代码才知道哪些情况没考虑到. #include<cstd ...
- ajax上传文件,并检查文件类型、检查文件大小
1.使用ajaxfileupload.js的插件,但是对插件做了一处修改,才能够正常使用 修改的部分如下: uploadHttpData: function (r, type) { var data ...
- 如何判断一个GPS点是否在以另一个GPS点为圆心100米为半径的圆内(Java代码)
题目乍一看,无从下手,仔细想了一下,原来只需要判断两个GPS点的直线距离是否<100米即可. Java代码如下: /** * 将两个经纬度坐标转化成距离(米) * * @param 2个GPS经 ...
- hiho_1079_离散化
题目 在长度为L的宣传栏上张贴N张海报,将宣传栏分为L个长度为1的单位,海报长度为整数,且高度和宣传栏相同,左右边界和宣传栏单位之间缝隙重合(即海报总是跨越整数个单位).后贴的海报可能会覆盖之前贴的海 ...
- vim 空格和换行的删除和替换
%s/\s//g %s/\r//g %s/\n//g 把一个很长的一行按空格分为多行 :%s/ +/\r/g简单解释一下:%s :在整个文件范围查找替换/ :分隔符+ :匹配空格,其中“ ”表 ...