亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

對(duì)一個(gè)26萬數(shù)據(jù)MYSQL表的Yii2程序優(yōu)化實(shí)戰(zhàn)之一 【去糟粕、加緩存】

LiuZh / 601人閱讀

摘要:記住它,一點(diǎn)點(diǎn)來,萬物均可優(yōu)化。下一篇將為你講解對(duì)一個(gè)萬數(shù)據(jù)的表程序優(yōu)化實(shí)戰(zhàn)真實(shí)例子之二開刀數(shù)據(jù)表完本文原創(chuàng)發(fā)布于微信公眾號(hào)北哥小報(bào)嚴(yán)謹(jǐn)?shù)脑瓌?chuàng)技術(shù)文,還有一些其他研究。

這是一篇真實(shí)案例,并不是理論課,阿北將同步我的整個(gè)優(yōu)化之路,優(yōu)化之路慢慢長(zhǎng),對(duì)大家拋磚引玉已達(dá)目的,若你也有一些優(yōu)化思路,請(qǐng)跟貼。

當(dāng)前系統(tǒng)情況

項(xiàng)目是年前一個(gè)朋友做的,客戶也是我的一個(gè)朋友,所以現(xiàn)在來幫忙優(yōu)化,系統(tǒng)很簡(jiǎn)單,就是一個(gè)菜單頁面,客戶下單,然后打印機(jī)出小票,整個(gè)系統(tǒng)使用yii2基礎(chǔ)版 + MySQL5.6.29驅(qū)動(dòng)。

客戶店里每天大約走1.5-2w的流水,現(xiàn)在最大的表有26w數(shù)據(jù),我切圖大家先看下。

從圖例看可能要優(yōu)化的地方

表引擎使用了MyISAM問題

order、order_box數(shù)據(jù)表瓶頸問題

我使用的工具

本地環(huán)境MAMP

yii2-debug 神器小強(qiáng)

yii2的各種緩存

優(yōu)化原則

代碼的修改最小化,盡量不動(dòng)核心代碼以防止引入bug,最后在進(jìn)行數(shù)據(jù)庫和服務(wù)器的優(yōu)化。

那咱就開始吧~

客戶說后臺(tái)登陸慢

當(dāng)我第一次聽客戶這樣說的時(shí)候,就已經(jīng)知道慢的絕對(duì)不是登陸,這個(gè)系統(tǒng)沒有權(quán)限、沒有很多日志、沒有登陸后的事件、僅僅就是一個(gè)登陸而已。

那很可能就是慢在登陸后進(jìn)入的第一個(gè)頁面而給客戶的感覺是登陸慢。

那就看看這個(gè)頁面

頁面邏輯很簡(jiǎn)單,就是一個(gè)銷售圖表,每天的銷售額曲線,那么問題最可能出現(xiàn)在這個(gè)圖表上,畢竟銷售額的計(jì)算看代碼都是從訂單實(shí)時(shí)分析出來的。

用yii2-debug看一看

果不其然,yii2-debug告訴我此action整個(gè)響應(yīng)時(shí)間為2.652秒,而數(shù)據(jù)庫就用了2.518秒,查詢次數(shù)39次...

看看每個(gè)查詢,每一天執(zhí)行一個(gè)SQL語句,每個(gè)都用了90毫秒左右,畢竟是26w數(shù)據(jù)中拿數(shù)據(jù)。

似乎問題明朗了,解決這個(gè)數(shù)據(jù)庫查詢就解決了這個(gè)頁面,先看看這個(gè)圖表的代碼實(shí)現(xiàn)

$y = date("Y",time()); //年
$m = date("m",time()); //月
$days_num = date("t",time()); //當(dāng)月天數(shù)

$days = "";
$moneys = "";
for($i=1; $i<=$days_num; $i++){
    $days .= $i.",";
    $begin_time = strtotime($y."-".$m."-".$i) + Yii::$app->params["business_hour"]["begin_time"];
    $end_time = strtotime($y."-".$m."-".$i) + Yii::$app->params["business_hour"]["end_time"];
    $money = Order::find()
        ->where([">","dish_id",0])
        ->andWhere(["pay_state"=>"pay"])
        ->andWhere([">=","pay_time",$begin_time])
        ->andWhere(["<=","pay_time",$end_time])
        ->andWhere(["store_id"=>Yii::$app->admin->identity->store_id])
        ->sum("money");
    $moneys .= ($money > 0 ? $money : 0).",";
}

優(yōu)化的步驟很簡(jiǎn)單:首先看能不能減少查詢次數(shù),如果不能就加速查詢,如果還不能就緩存結(jié)果。

在這段代碼中,無論今日是幾號(hào),都進(jìn)行了整月天數(shù)的查詢,我先來去掉不該進(jìn)行的查詢。

修改及其簡(jiǎn)單,只是增加了3行代碼

for($i=1; $i<=$days_num; $i++){
    $days .= $i.",";
    if($i > date("d",time())){
        $moneys .= "0,";
        continue;
    }
    ........
}

但是通過減少不必要的查詢的結(jié)果是

數(shù)據(jù)庫檢索從39減少到30次,耗時(shí)從2.518秒減少到1.982秒。

對(duì)于加速查詢無外乎表類型選擇及索引的添加,本著表是所有action的表,蒼老師是世界的蒼老師,我先不動(dòng),只是記錄下dish_id、pay_state、pay_time、store_id四個(gè)字段,后面對(duì)order表進(jìn)行改造的時(shí)候再考慮他們。

然后對(duì)于這種統(tǒng)計(jì)類數(shù)據(jù),沒有必要每次都實(shí)時(shí)讀取,我應(yīng)該加一個(gè)緩存。

加個(gè)文件類型緩存

如果你不會(huì)玩Yii2緩存,請(qǐng)移步到 Yii2緩存系列 先學(xué)習(xí)。

看這個(gè)圖表和當(dāng)下代碼,我的緩存可以按照月份來,但是還要保證當(dāng)天銷量的實(shí)時(shí)性,所以我緩存的是本月今天之前的數(shù)據(jù)。

首先去配置文件 config/web.php 設(shè)置

// conf/web.php
...
"cache" => [
    "class" => "yiicachingFileCache",
],
...

采用默認(rèn)的就好,代碼進(jìn)行一點(diǎn)小手術(shù)(將今天之前的代碼多帶帶處理),核心邏輯不變。

$cache = Yii::$app->cache;
$cacheKey = "month-report-{$m}";

$days = "";
$moneys = "";

//  今天之前的數(shù)據(jù),也是我們要緩存的數(shù)據(jù)
$monthDatBeforeToday = $cache->get($cacheKey);
if ($monthDatBeforeToday === false) {
    for($i = 1;$i < date("d",time());$i++){
        $days .= $i.",";
        $begin_time = strtotime($y."-".$m."-".$i) + Yii::$app->params["business_hour"]["begin_time"];
        $end_time = strtotime($y."-".$m."-".$i) + Yii::$app->params["business_hour"]["end_time"];
        $money = Order::find()
            ->where([">","dish_id",0])
            ->andWhere(["pay_state"=>"pay"])
            ->andWhere([">=","pay_time",$begin_time])
            ->andWhere(["<=","pay_time",$end_time])
            ->andWhere(["store_id"=>Yii::$app->admin->identity->store_id])
            ->sum("money");
        $moneys .= ($money > 0 ? $money : 0).",";
    }
    $monthDatBeforeToday = ["days"=>$days,"moneys"=>$moneys];
    $cache->set($cacheKey,$monthDatBeforeToday,7200);
}

$days = $monthDatBeforeToday["days"];
$moneys = $monthDatBeforeToday["moneys"];

for($i=date("d",time());$i<=$days_num; $i++){
    $days .= $i.",";
    if($i > date("d",time())){
        $moneys .= "0,";
        continue;
    }

    $begin_time = strtotime($y."-".$m."-".$i) + Yii::$app->params["business_hour"]["begin_time"];
    $end_time = strtotime($y."-".$m."-".$i) + Yii::$app->params["business_hour"]["end_time"];
    $money = Order::find()
        ->where([">","dish_id",0])
        ->andWhere(["pay_state"=>"pay"])
        ->andWhere([">=","pay_time",$begin_time])
        ->andWhere(["<=","pay_time",$end_time])
        ->andWhere(["store_id"=>Yii::$app->admin->identity->store_id])
        ->sum("money");
    $moneys .= ($money > 0 ? $money : 0).",";
}

當(dāng)然,從編寫上講,這段代碼可以繼續(xù)優(yōu)化,但是在原理上已經(jīng)完成了,我將今天之前的數(shù)據(jù)都緩存下來,今天的實(shí)時(shí)讀取,這樣就滿足了這個(gè)圖表和原來一樣的結(jié)果,為防止其他地方對(duì)訂單的修改,換成我2個(gè)小時(shí)更新一次。

用yii2-debug看看結(jié)果。

你沒看錯(cuò)

數(shù)據(jù)庫從39次到10次,耗時(shí)從2.518秒到0.1秒

Action執(zhí)行從2.652秒減少到0.212秒

初步使用我們Yii2優(yōu)化三原則中的兩條,Action執(zhí)行提高了12倍、數(shù)據(jù)庫耗時(shí)減少了23倍。

優(yōu)化的步驟很簡(jiǎn)單:首先看能不能減少查詢次數(shù),如果不能就加速查詢,如果還不能就緩存結(jié)果。

記住它,一點(diǎn)點(diǎn)來,萬物均可優(yōu)化。

還有很多

這僅僅是對(duì)統(tǒng)計(jì)數(shù)據(jù)采用緩存小試牛刀,如果對(duì)于訂單列表這種檢索那就要用到第二條原則了(如何讓查詢語句更快)。

下一篇將為你講解 對(duì)一個(gè)26萬數(shù)據(jù)的MYSQL表Yii2程序優(yōu)化實(shí)戰(zhàn)(真實(shí)例子)之二 【開刀數(shù)據(jù)表】

(完)

本文原創(chuàng)發(fā)布于微信公眾號(hào) 北哥小報(bào) , 嚴(yán)謹(jǐn)?shù)脑瓌?chuàng)技術(shù)文,還有一些其他研究。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/61866.html

相關(guān)文章

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<