php性能優(yōu)化之不要在for循環(huán)中操作DB_第1頁(yè)
php性能優(yōu)化之不要在for循環(huán)中操作DB_第2頁(yè)
php性能優(yōu)化之不要在for循環(huán)中操作DB_第3頁(yè)
php性能優(yōu)化之不要在for循環(huán)中操作DB_第4頁(yè)
php性能優(yōu)化之不要在for循環(huán)中操作DB_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論