v2.5.2
Giriş yap

Php sorgu hızlandırma

Anonim
510 defa görüntülendi

Merhaba, aşağıda bulunan kod yapısını sorgu hızı bakımından nasıl kısaltılabilir veya hızlandırılabilir ?


  $detail = $this->connect->query("SELECT ES.orderId,ES.totalDiscount,ES.totalPrice,ES.orderDate,ES.PackageStatus,ES.Platform,ES.orderStatus,EC.customerfullName as customerNameSurname,(SELECT count(customerfullName) from entg_sales_customer where customerfullName=customerNameSurname) customerOrderCount FROM entg_sales ES LEFT JOIN entg_sales_customer EC ON ES.orderId = EC.orderId and ES.auth = EC.auth WHERE ES.orderDate BETWEEN '$orderDate' AND '$orderEndDate' AND (ES.auth = '$this->appkey' and ES.orderStatus='$orderStatus') ORDER BY ES.id DESC");
            $rowPD = $detail->rowCount();
            $orderList = [];
            if ($rowPD > 0) {
                $detail = $detail->fetchAll(PDO::FETCH_ASSOC);
                foreach ($detail as $keys) {
                    $orderId = $keys["orderId"];
                    $detail = $this->connect->query("select orderId,packageId,totalDiscount,totalPrice,orderDate,agreedDeliveryDate,Platform,orderStatus from entg_sales where orderId='$orderId' and auth='$this->appkey'")->fetch(PDO::FETCH_ASSOC);
                    $adress = $this->connect->query("select firstName,lastName,fullName,address,city,district,type,fullAddress from entg_sales_adress where orderId='$orderId' and auth='$this->appkey'")->fetchAll(PDO::FETCH_ASSOC);
                    $cargoDetail = $this->connect->query("SELECT cargoTrackingNumber,cargoProviderName,cargoPrice FROM entg_sales_cargo where orderId='$orderId' and auth='$this->appkey'")->fetch(PDO::FETCH_ASSOC);
                    $customerDetail = $this->connect->query("SELECT customerFirstName,customerLastName,customerEmail,customerFullName,tcIdentityNumber,taxOffice,taxId FROM entg_sales_customer where orderId='$orderId' and auth='$this->appkey'")->fetch(PDO::FETCH_ASSOC);
                    $list = $this->connect->query("SELECT ESD.barcode, ESD.productName, ESD.productCode, ESD.merchantCode, ESD.productSize, ESD.quantity, ESD.amount, ESD.discount, ESD.price, ESD.attributeValue, ESD.Tax, ESD.salesCampaignId, EP.barcode, PM.imageName, P.purchase, P.purchaseTax, P.discount1, P.discount2, P.discount3, P.tax FROM entg_sales_detail ESD LEFT JOIN entg_product EP ON ESD.barcode = EP.barcode AND ESD.auth = EP.auth LEFT JOIN product_images PM ON EP.mainBarcode = PM.barcode AND EP.auth = PM.auth LEFT JOIN product P ON P.barcode = PM.barcode AND P.auth = PM.auth WHERE ESD.orderId = '$orderId' AND ESD.auth = '$this->appkey' GROUP BY EP.mainBarcode")->fetchAll(PDO::FETCH_ASSOC);
                    $orderJson = [
                        "detail" => $detail,
                        "adress" => $adress,
                        "cargoDetail" => $cargoDetail,
                        "customerDetail" => $customerDetail,
                        "list" => $list
                    ];
                    $orderList[] = $orderJson;
                }
            } 

ebykdrms
585 gün önce

Bir kez daha bakınca aslında daha kısa SQL oluşmasını sağlayabilirmişiz gibi göründü.
Mesela ilk foreach döngüsünde oluşturup $whereCondition değişkenine atadığımız string örnek olarak şöyle:
(orderId='123' auth='abc') OR (orderId='131' auth='abc') OR (orderId='213' auth='abc')
yani aslında auth sütunu hep aynı. O halde bunu tek bir AND ifadesiyle birleştirebilirdik. Yani:
auth='abc' AND (orderId='123' OR orderId='131' OR orderId='213')
şeklinde yazabilirdik. Muhtemelen az da olsa MySQL için de daha rahat bir sorgu olacaktır. İki sütunu her OR bloğu için kontrol etmemiş olur.
Bu durumda aşağıdaki şu satırları:

foreach ($detail as $keys) {
    $whereConditions[] = "(orderId='" . $keys["orderId"] . "' AND auth='" . $this->appkey . "')";
    $whereConditionsWithESD[] = "(ESD.orderId='" . $keys["orderId"] . "' AND ESD.auth='" . $this->appkey . "')";
}
$whereCondition = implode(" OR ", $whereConditions);
$whereConditionWithESD = implode(" OR ", $whereConditionsWithESD);

şu şekilde değiştirmek daha yerinde olur:

foreach ($detail as $keys) {
    $orderId = $keys["orderId"];
    $whereConditions[] = "orderId='$orderId'";
    $whereConditionsWithESD[] = "ESD.orderId='$orderId'";
}
$whereCondition = implode(" OR ", $whereConditions);
$whereConditionWithESD = implode(" OR ", $whereConditionsWithESD);

$appKey = $this->appkey;
$whereCondition = "auth='$appKey' AND ($whereCondition)";
$whereConditionWithESD = "ESD.auth='$appKey' AND ($whereCondition)";

Böylece satır sayısı biraz arttı ama MySQL için daha rahat bir sorgu oluşturduk.

Aşağıdaki satırlarda sanırım $orderList objesindeki değer kodunuzdaki diğer kurgularla uyuşmadığı için yeni bir formata çevirerek orderId değerlerine göre gruplamışsınız.
O kısmı şu şekilde değiştirirseniz daha kısa kodla işi çözebilirsiniz sanıyorum.
Yani yukarıdaki kodlardan sonra gelen kodlarınızdaki $orderListESD = []; ile başlayıp $orderList = $orderListESD; ile biten kısmı komple silip yerine şunu yazabilirsiniz:

$relationalOrderList = [];
foreach($orderList["detail"] as $detail) {
    $orderId = $detail["orderId"];
    $relationalOrderList[] = [
        "detail" => $detail,
        "address" => array_filter($orderList["address"], function($item){ return $item["orderId"]===$orderId; }),
        "cargoDetail" => array_filter($orderList["cargoDetail"], function($item){ return $item["orderId"]===$orderId; }),
        "customerDetail" => array_filter($orderList["customerDetail"], function($item){ return $item["orderId"]===$orderId; }),
        "list" => array_filter($orderList["list"], function($item){ return $item["orderId"]===$orderId; }),
    ];
}
$orderList = $relationalOrderList;