0

PHP/MySQLを使用しています

私は約2,000の製品を持っています。各製品の過去6、3、1か月の平均月間売上高を計算し、それを一度にページに表示する必要があります...

現在、次のコードがあります(製品ごとにループします)。

$past_month_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                $item_code, $past_month[0],
                                                                $past_month[1] );

$past_two_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_two_months[0],
                                                                    $past_two_months[1] );

$past_three_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_three_months[0],
                                                                    $past_three_months[1] );

$past_four_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_four_months[0],
                                                                    $past_four_months[1] );

$past_five_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_five_months[0],
                                                                    $past_five_months[1] );

$past_six_months_sales = $this->SalesPerProduct->getSalesForMonthYear( $acc_code,
                                                                    $item_code, $past_six_months[0],
                                                                    $past_six_months[1] );

//for past 3 months
if( $past_month_sales == 0
    || $past_two_months_sales == 0
    || $past_three_months_sales == 0){

    $past_three_sales_ave = "n/a";

}else{

    $past_three_sales_ave = round( ( $past_month_sales 
                        + $past_two_months_sales
                        + $past_three_months_sales )
                        / 3 );
}

//for past 6 months
if( $past_month_sales == 0
    || $past_two_months_sales == 0
    || $past_three_months_sales == 0
    || $past_four_months_sales == 0
    || $past_five_months_sales == 0
    || $past_six_months_sales == 0){

    $past_six_sales_ave = "n/a";

}else{
    $past_six_sales_ave = round( ( $past_month_sales
                        + $past_two_months_sales
                        + $past_three_months_sales
                        + $past_four_months_sales
                        + $past_five_months_sales
                        + $past_six_months_sales )
                        / 6 );
}

しかし、上記のコードは非常に遅く、100個の製品でさえロードに時間がかかります...

getSalesForMonthYear関数は次のようになります。

function getSalesForMonthYear( $account_code, $item_code, $month, $year ){
    $sql = "select 
                SalesPerProduct.sales_value
            from 
                sales_per_products as SalesPerProduct
            where
                account_code = '{$account_code}' and
                item_code = '{$item_code}' and
                month = '{$month}' and
                year = '{$year}'";

    $val = $this->query($sql);

    if( empty( $val[0]['SalesPerProduct']['sales_value'] ) ){
        $val = 0;
    }else{
        $val = $val[0]['SalesPerProduct']['sales_value'];
    }
    return $val;
}

これがどのように速くなることができるかについて何か考えはありますか?TIA !!!

4

3 に答える 3

1

クリックが発生するたびにデータを更新する必要はないため、キャッシュテーブルを作成してデータを保存し、必要な期間ごとに更新します

于 2012-08-10T08:51:31.120 に答える
0

多分一般的な関数を使用し、毎月チェックしないでください。月とsales_valueのインデックスを使用してみてください

/*
   $account_code - account
   $item_code - item
   $start_month - starting month - NOTE: this is integer: 1,2,....,10,11,12
   $months - number of months to query
   $year - the year
   and SUM to auto calculate the sales_value
*/
function getSalesForMonths( $account_code, $item_code, $start_month, $months, $year ){
    $addQuery = '';
    $finalQuery = '';

    for($i = 1; $i<=$months; $i++){
         $addQuery .= 'month='.($start_month+$i);
         if($i<$months){ $addQuery .= ' OR '; }
    }

    if($months > 1){
        $finalQuery = '('.$addQuery.')';
    } else {
        $finalQuery = $addQuery;
    }

    $sql = "select 
            SUM(SalesPerProduct.sales_value)
        from 
            sales_per_products as SalesPerProduct
        where
            account_code = '{$account_code}' and
            item_code = '{$item_code}' and
            ".$finalQuery." and
            year = '{$year}'";

    $val = $this->query($sql);

    if( empty( $val[0]['SalesPerProduct']['sales_value'] ) ){
        $val = 0;
    }else{
        $val = $val[0]['SalesPerProduct']['sales_value'];
    }
    return $val;
}
于 2012-08-10T08:55:30.270 に答える
0

AVGのようなSQLコマンドを調べる必要があります

http://www.w3schools.com/sql/sql_func_avg.asp

データベース側で計算を行う方が常に良いです。あなたが書いたコードは、それを抽出する前にそれを行うよりも速く進むことはありません。

データベースのインデックスが適切に作成されていることを確認して、データベースがいつ何をすべきかを把握できるようにします。

それがあなたができる最初のことです!

私はそれがこの時点であなたのためにたくさん解決すると思います。

その後、さらに一歩進めたい場合は、これにチェックインできます。

http://www.sqlteam.com/article/intro-to-user-defined-functions-updated http://www.w3schools.com/sql/sql_view.asp

1つのSQLクエリですべての平均呼び出しを抽出する関数とビューを作成できます。複数の接続は必要ありません。すべての接続には、起動時のオーバーヘッドなどがあり、データベース側ですべてを実行することで、再度パスすることができます。

于 2012-08-10T08:49:57.207 に答える