真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

數(shù)據(jù)庫優(yōu)化的三個例子

在維護(hù)舊數(shù)據(jù)庫的時候經(jīng)常碰到非常的查詢,多數(shù)都是兩方面的原因。
1)沒有加索引
2)查詢語句導(dǎo)致索引用不上
3)過多的連接數(shù)據(jù)庫

成都創(chuàng)新互聯(lián)公司2013年開創(chuàng)至今,先為靈璧等服務(wù)建站,靈璧等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為靈璧企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。


例子1:

在一個大型的計(jì)算中原來每天要花費(fèi)半小時才能完成,對計(jì)算的過程進(jìn)行仔細(xì)的分析,發(fā)現(xiàn)下面的語句花費(fèi)了很長時間

select sum(order_qty - delivery_qty - reduce_confirm_qty - lost_qty ) qty from circle_ordering where sku = '" . $sku . "' AND submit_status = 5 AND order_type = 'AIR'

通過explain 這條語句,仔細(xì)分析數(shù)據(jù)庫才知道并沒有相關(guān)的索引作用在這條查詢語句上,這樣導(dǎo)致了這條sql是全表查詢。于是對這三列(sku, submit_status, order_type)新建索引. 重新執(zhí)行后,整個程序只用了10份鐘就完成了。

例子2:

select a.ebay_id, b.ebay_id as ebay_subid, from_unixtime(a.ebay_paidtime) as ebay_paidtime,
                                      a.ebay_account, a.ebay_countryname, c.store_name as warehouse, a.ebay_carrier,
                                      b.sku, b.ebay_amount, a.ebay_currency, b.ebay_itemprice,
                                      b.shipingfee,  ((b.ebay_itemprice*b.ebay_amount)+b.shipingfee) as total_amount, ebay_postcode,
                                      b.item_promotion_discount_amount, b.ship_promotion_discount_amount

                                    from ebay_order a left join ebay_orderdetail b on(a.ebay_ordersn=b.ebay_ordersn) 
                                                      left join ebay_store c on (a.ebay_warehouse = c.id)
                                    where a.ebay_combine !=1 and (a.resend_org_ebay_id=0 or a.resend_org_ebay_id is null) and 
                                          b.ebay_amount >0 and a.ebay_warehouse !='' and a.ebay_user='manwei' 

                                            and                                             

                                          (

                                            a.ebay_paidtime between UNIX_TIMESTAMP('".$astart."') and UNIX_TIMESTAMP('".$aend."') 

                                            or
                                          (a.ebay_paidtime not between UNIX_TIMESTAMP('".$astart_p."') and UNIX_TIMESTAMP('".$aend_p."')  and 
                                           a.shippedtime between UNIX_TIMESTAMP('".$astart_p."') and UNIX_TIMESTAMP('".$aend_p."')) ";

                                        if($last_ebay_id!='') $data .= " or a.ebay_id >='".$last_ebay_id."'";

                                        $data .=  ") order by a.ebay_id, b.ebay_id ";

注意這個復(fù)雜的查詢語句的條件

第一個條件
(a.ebay_paidtime between UNIX_TIMESTAMP('".$astart."') and UNIX_TIMESTAMP('".$aend."')
由于在ebay_paidtime字段有索引,如果只有這個條件,查詢速度很快,查詢一次不到一秒。但是因?yàn)楹竺孢€有兩個條件使用了 or, 這樣導(dǎo)致會導(dǎo)致了對ebay_order進(jìn)行了全表查詢,而這個表有3百多萬條數(shù)據(jù),所以查詢非常慢。
(有這個說法 :驗(yàn)證在兩個相同字段之間使用or不會導(dǎo)致全表掃描,只有出現(xiàn)不同字段自建使用or時會導(dǎo)致全表掃描。但我沒有驗(yàn)證過。)

根據(jù)業(yè)務(wù)需求我們把三個用or 連接的查詢條件拆出來,分別進(jìn)行查詢,最后用union語句連起來。這樣查詢的效率得到了大大的提高。修改后的查詢?nèi)缦?/p>

$data1 ="select " . $fields_list . "
                                    from ebay_order a left join ebay_orderdetail b on(a.ebay_ordersn=b.ebay_ordersn) 
                                                      left join ebay_store c on (a.ebay_warehouse = c.id)
                                    where a.ebay_combine !=1 and (a.resend_org_ebay_id=0 or a.resend_org_ebay_id is null) and 
                                          b.ebay_amount >0 and a.ebay_warehouse !='' and a.ebay_user='manwei' 
                                          and  a.ebay_paidtime between UNIX_TIMESTAMP('".$astart."') and UNIX_TIMESTAMP('".$aend."')";

  $data2 = "select " . $fields_list . "
                                    from ebay_order a left join ebay_orderdetail b on(a.ebay_ordersn=b.ebay_ordersn) 
                                                      left join ebay_store c on (a.ebay_warehouse = c.id)
                                    where a.ebay_combine !=1 and (a.resend_org_ebay_id=0 or a.resend_org_ebay_id is null) and 
                                          b.ebay_amount >0 and a.ebay_warehouse !='' and a.ebay_user='manwei' 
                                          and (
                                                a.shippedtime between UNIX_TIMESTAMP('".$astart_p."') and UNIX_TIMESTAMP('".$aend_p."') and
                                                a.ebay_paidtime not between UNIX_TIMESTAMP('".$astart."') and UNIX_TIMESTAMP('".$aend."') 
                                           )";

    if($last_ebay_id!='') {
             $data3 = "select " . $fields_list . "
                                    from ebay_order a left join ebay_orderdetail b on(a.ebay_ordersn=b.ebay_ordersn) 
                                                      left join ebay_store c on (a.ebay_warehouse = c.id)
                                    where a.ebay_combine !=1 and (a.resend_org_ebay_id=0 or a.resend_org_ebay_id is null) and 
                                          b.ebay_amount >0 and a.ebay_warehouse !='' and a.ebay_user='manwei' 
                                          and a.ebay_id >='" .$last_ebay_id ."'";
   }

    $data = "(" . $data1 . ")";
  if($data2 != "") $data = $data . " union (". $data2 . ")";
  if($data3 != "") $data = $data . " union (". $data3 . ")";

小插曲,當(dāng)我們分析data2的時候,無論如何給shippedtime加索引,只要查詢shippedtime都是全表查詢。仔細(xì)分析才知道原來在數(shù)據(jù)庫設(shè)計(jì)的時候,這個shippedtime的字段是varchar, 程序把時間戳保存成這種類型,自然沒有辦法使用適合我們需要的索引,解決的方法是通過alter語句先把shippedtime改成int 類型,再增加一個索引到這個字段。這樣這個查詢慢的問題就徹底得到解決了。

例子3:

$data = $isfesdb->query($data);
$quan = $isfesdb->num_rows($data);

for($i=0;$i<$quan;$i++){
{
            ...
            $vv             = "select goods_name, goods_weight from ebay_goods where goods_sn='".$sku[$i]."' limit 1";
            $vv             = $isfesdb->execute($vv);
            $vv             = $isfesdb->getResultArray($vv);

            if(count($vv)==0){                      

                            ...
                            $sku[$i]   = str_replace('-FBA-FR','',$sku[$i]);                                    
                            ...

                        }

            ...
}

從代碼上看,這個只是很簡單的查詢,ebay_goods也有索引,應(yīng)該很快就能查詢到結(jié)果。但實(shí)際上整個流程跑下來很慢。仔細(xì)分析原因是因?yàn)?quan的數(shù)字太大,導(dǎo)致了for循環(huán)超過了10000次,這樣導(dǎo)致了$vv這個查詢進(jìn)行了10000次。所以單獨(dú)查一條沒有性能問題,但是如果多次重復(fù)這樣的查詢就會引起性能問題。

解決的方法就是在for循環(huán)的前面先查詢ebay_goods全表,把這個表記錄到一個數(shù)組,然后在for循環(huán)里使用素組的數(shù)據(jù)。因?yàn)閑bay_goods這個數(shù)組只有幾千條記錄,這個方法是可行的。
修改程序變成:

$vv = $isfesdb->query("select goods_sn, goods_name, goods_weight from ebay_goods");
$vv_quan = $isfesdb->num_rows($vv);
$vv_result = $isfesdb->getResultArray($vv);

for($i=0; $i<$vv_quan; $i++) {
        $goods_array[$vv_result[$i]['goods_sn']] = array($vv_result[$i]['goods_name'], $vv_result[$i]['goods_weight']); 
        }

for($i=0;$i<$quan;$i++)
{
...

     if(!array_key_exists($sku[$i], $goods_array)){

             ...
             $sku[$i]   = str_replace('-FBA-FR','',$sku[$i]);                                   
             ...

     }

 ...
 }

我們采用數(shù)組的方法后,查詢也比舊方法效率提高好幾倍。這是因?yàn)楝F(xiàn)在我們的服務(wù)器配置的內(nèi)存是足夠大的,PHP的運(yùn)行也是足夠快的。瓶頸就在于php在等待MySQL的查詢結(jié)果。所以我們先用一次查詢把數(shù)據(jù)庫結(jié)果組成了數(shù)組。


新聞名稱:數(shù)據(jù)庫優(yōu)化的三個例子
分享鏈接:http://weahome.cn/article/popicp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部