版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第php性能優(yōu)化之不要在for循環(huán)中操作DB目錄前言場(chǎng)景說(shuō)明舉例說(shuō)明進(jìn)一步優(yōu)化性能對(duì)比
前言
如何提高程序運(yùn)行速度,減輕服務(wù)器壓力是服務(wù)端開(kāi)發(fā)必須面對(duì)的一個(gè)問(wèn)題。
簡(jiǎn)單且樸素的原則:不要在for循環(huán)中操作DB,包括關(guān)系型數(shù)據(jù)庫(kù)和NoSql。
我們應(yīng)該根據(jù)自己的業(yè)務(wù)場(chǎng)景,在for循環(huán)之前批量拿到數(shù)據(jù),用盡量少的sql查詢(xún)批量查到結(jié)果。在for循環(huán)中進(jìn)行數(shù)據(jù)的匹配組裝。
場(chǎng)景說(shuō)明
業(yè)務(wù)在多個(gè)情景下需要獲得用戶(hù)的詳細(xì)信息,有點(diǎn)可以通過(guò)查詢(xún)用戶(hù)表直接獲取到,有的需要查詢(xún)關(guān)聯(lián)關(guān)系表獲取到,有的只保存了關(guān)聯(lián)的id,并沒(méi)有單獨(dú)創(chuàng)建關(guān)聯(lián)關(guān)系表,需要單獨(dú)寫(xiě)獲取函數(shù)取值。既然多個(gè)場(chǎng)景下需要調(diào)用,那么封裝成一個(gè)公共方法,讓多個(gè)場(chǎng)景統(tǒng)一調(diào)用公共方法是基本的優(yōu)化思路。上面提到了復(fù)雜的存取值關(guān)系,我們需要分析一下,哪些操作是耗時(shí)的,耗時(shí)的操作如何優(yōu)化,能否減少sql查詢(xún)的次數(shù)。
舉例說(shuō)明
下面的代碼示例,我們封裝了CommonRender的類(lèi),所有可以統(tǒng)一輸出的方法都在這里下面代碼標(biāo)注了優(yōu)化之前和優(yōu)化之后優(yōu)化之前:在每次查詢(xún)都需要根據(jù)保存的id,去數(shù)據(jù)庫(kù)查詢(xún);如果列表頁(yè)每次返回30條數(shù)據(jù),那這部分就需要30次sql查詢(xún)。優(yōu)化之后:采用的是提前批量取值,又寫(xiě)了一個(gè)函數(shù)_renderHobby,只需要1次sql。這樣就極大的減少了sql查詢(xún),提高了程序響應(yīng)的速度。
php
namespaceApp\Render;
classCommonRenderextendsBaseRender
publicstaticfunctionrenderUserinfo($data,$hobbyInfo=[])
if(!is_array($data)){
return[];
$ret=[
'uid'=!isset($data['id'])0:$data['id'],
'userid'=!isset($data['userid'])'':$data['userid'],
'username'=!isset($data['username'])'':$data['username'],
'usericon'=!isset($data['usericon'])[]:$data['usericon'],
//優(yōu)化之前
//'hobby'=!isset($data['hobby'])[]:HobbyInfo::getByIds($data['hobby']),
//優(yōu)化之后
'hobby'=!isset($data['hobby'])[]:self::_renderHobby($data['hobby'],$hobbyInfo),
if(!empty($ret['birth'])){
$ret['zodiacSign']=Utility::getZodiacSign($ret['birth']);
}else{
$ret['zodiacSign']='';
return$ret;
protectedstaticfunction_renderHobby($userHobby,$hobbyInfo)
$ret=[];
if($userHobby){
$userHobbyIds=explode(',',$userHobby);
foreach($userHobbyIdsas$key=$userHobbyId){
$ret[$key]=$hobbyInfo[$userHobbyId];
return$ret;
//用戶(hù)列表卡片常用字段
publicstaticfunctionrenderListCardUserinfo($data)
進(jìn)一步優(yōu)化
上面的代碼已經(jīng)優(yōu)化了性能,但是還不夠優(yōu)雅。
獲取單用戶(hù)信息場(chǎng)景比較多,比如編輯,登錄,查看單人信息等,這種情況下我還每次都提前批量查詢(xún)嗎?這樣的話(huà)需要改造的地方太多了。
下面做進(jìn)一步優(yōu)化:
在render方法內(nèi)部封裝了一層,如果外部沒(méi)有傳入或傳入空數(shù)組,自己再查詢(xún)db獲得一次需要的數(shù)據(jù)源。
php
namespaceApp\Render;
classCommonRenderextendsBaseRender
publicstaticfunctionrenderUserinfo($data,$hobbyInfo=[])
//區(qū)別在這里:批量查詢(xún)外部傳入,減少sql查詢(xún)次數(shù);單次查詢(xún)?cè)趓ender內(nèi)查一次
$hobbyInfo=!empty($hobbyInfo)$hobbyInfo:HobbyInfo::getAllInfo();
if(!is_array($data)){
return[];
$ret=[
'uid'=!isset($data['id'])0:$data['id'],
'userid'=!isset($data['userid'])'':$data['userid'],
'username'=!isset($data['username'])'':$data['username'],
'usericon'=!isset($data['usericon'])[]:$data['usericon'],
//優(yōu)化之前
//'hobby'=!isset($data['hobby'])[]:HobbyInfo::getByIds($data['hobby']),
//優(yōu)化之后
'hobby'=!isset($data['hobby'])[]:self::_renderHobby($data['hobby'],$hobbyInfo),
if(!empty($ret['birth'])){
$ret['zodiacSign']=Utility::getZodiacSign($ret['birth']);
}else{
$ret['zodiacSign']='';
return$ret;
protectedstaticfunction_renderHobby($userHobby,$hobbyInfo)
$ret=[];
if($userHobby){
$userHobbyIds=explode(',',$userHobby);
foreach($userHobbyIdsas$key=$userHobbyId){
$ret[$key]=$hobbyInfo[$userHobbyId];
return$ret;
//用戶(hù)列表卡片常用字段
publicstaticfunctionrenderListCardUserinfo($data)
這樣,那些獲得單個(gè)用戶(hù)資料的方法就不需要修改了。
//編輯用戶(hù)資料
publicfunctioneditUserInfo(Request$request)
$userInfo=UserInfo::editUserById($this-_userid,$request);
return[
'user'=
CommonRender::renderUserinfo($userInfo)
+UserInfo::formatCoverAndPickedFootprint($userInfo)
性能對(duì)比
批量獲得用戶(hù)信息對(duì)比:性能提升立竿見(jiàn)影。
比如每次取30個(gè)用戶(hù)數(shù)據(jù),之前獲得愛(ài)好,職業(yè),期望部分要查詢(xún)30次db。優(yōu)化之后只需要查詢(xún)3次db。
publicstaticfunctiongetBatchUserIntro($userid,$userList)
$retData=[];
if(empty($userList)){
return$retData;
//批量獲得愛(ài)好、職業(yè)、期望遇到在foreach中計(jì)算取值,不重復(fù)請(qǐng)求DB取值
$hobbyInfo=HobbyInfo::getAllInfo();
$professionInfo=ProfessionInfo::getAllInfo();
$expectInfo=ExpectInfo::getAllInfo();
foreach($batchUserInfoas$item){
$retData[$item['userid']]=array_merge(
['wxnumber'=Utility::maskWxnumber($item['wxnumber'],$batchExchangeStatus[$item['userid']]==UserUserWeixinExchange::TYPE_TRUE)]
+
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 硅芯制備工安全宣貫測(cè)試考核試卷含答案
- 栲膠蒸發(fā)工崗前實(shí)操知識(shí)技能考核試卷含答案
- 油母頁(yè)巖供料工崗前創(chuàng)新思維考核試卷含答案
- 2022-2023學(xué)年吉林省白山市普通高校對(duì)口單招綜合素質(zhì)自考真題(含答案及部分解析)
- 2025年本地網(wǎng)傳輸系統(tǒng)合作協(xié)議書(shū)
- 2025年原油加工量合作協(xié)議書(shū)
- 2025年LED超大屏幕顯示器項(xiàng)目發(fā)展計(jì)劃
- 三級(jí)安全教育考試卷(附答案)
- 醫(yī)院檢驗(yàn)科年度工作總結(jié)及計(jì)劃
- 2026營(yíng)養(yǎng)師基礎(chǔ)知識(shí)試題及答案
- 特殊作業(yè)之-斷路作業(yè)安全教育培訓(xùn)
- 中華醫(yī)學(xué)會(huì)麻醉學(xué)分會(huì)困難氣道管理指南
- 醫(yī)務(wù)部會(huì)議管理制度范本
- 繪本制作培訓(xùn)課件
- 客戶(hù)分配管理辦法管理
- 燃?xì)馊霊?hù)安檢培訓(xùn)
- 高中地理思政融合課《全球氣候變暖》
- 《山東省市政工程消耗量定額》2016版交底培訓(xùn)資料
- 《中醫(yī)六經(jīng)辨證》課件
- 掛名合同協(xié)議書(shū)
- 蘇教版高中化學(xué)必修二知識(shí)點(diǎn)
評(píng)論
0/150
提交評(píng)論