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
590 gün önce

foreach içinde sql sorgusu atmamalısınız.
Hepsinde ortak olan sanırım orderId ve auth sütunları.
İlk sorgunuzdan sonra bu orderId ve auth değerlerini bir string içinde birleştirin ve or'larla birbirine bağlayın.

$detail = $this->connect->query("...");
$rowPD = $detail->rowCount();
$orderList = [];
$whereConditions = [];
$whereConditionsWithESD = [];
if ($rowPD > 0) {
    $detail = $detail->fetchAll(PDO::FETCH_ASSOC);
    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);
    
    $detail = $this->connect->query("... WHERE $whereCondition")->fetch(PDO::FETCH_ASSOC);
    $adress = $this->connect->query("... WHERE $whereCondition")->fetchAll(PDO::FETCH_ASSOC);
    $cargoDetail = $this->connect->query("... WHERE $whereCondition")->fetch(PDO::FETCH_ASSOC);
    $customerDetail = $this->connect->query("... WHERE $whereCondition")->fetch(PDO::FETCH_ASSOC);
    $list = $this->connect->query("... WHERE $whereConditionWithESD ...")->fetchAll(PDO::FETCH_ASSOC);
    $orderList = [
        "detail" => $detail,
        "adress" => $adress,
        "cargoDetail" => $cargoDetail,
        "customerDetail" => $customerDetail,
        "list" => $list
    ];
}

Sorgularınızın içeriğini bilmiyorum ama hepsinin WHERE koşulu aynı. sadece WHERE koşullarını yukarıdaki gibi düzenleyebilirsiniz.
Örneğin foreach içindeki ilk 4 sorgunuzdaki
where orderId='$orderId' and auth='$this->appkey'
yerine
WHERE $whereCondition yazacaksınız.
$list için olan son sorguda da
WHERE ESD.orderId = '$orderId' AND ESD.auth = '$this->appkey'
yerine
WHERE $whereConditionWithESD yazacaksınız.

Böylece mesela $detail için her foreach döngüsünde
WHERE orderId='123' auth='abc',
WHERE orderId='131' auth='abc',
WHERE orderId='213' auth='abc' şeklinde yazıp istek atmadık da,
tek bir $detail sorgusu için
WHERE (orderId='123' auth='abc') OR (orderId='131' auth='abc') OR (orderId='213' auth='abc')
şeklinde istek attık.

Yani mesela ilk sorgunuzdan 3 tane orderId döndüyse
foreach içindeki 5 sorgunuz 3 defa çalışacak ve MySQL'e 15 defa istek atacaksınız.
Yeni durumdaysa kaç tane orderId olursa olsun MySQL'e sadece 6 istek atacaksınız.
Veritabanına mümkün olduğunca az istek atılmalı. Bu işlem tek başına daha hızlı sonuç almanızı sağlayacaktır.
Eğer $list sorgunuzda olduğu gibi diğer sorguları da tek sorguda birleştirme şansınız varsa çok daha iyi sonuç alırsınız.
MySQL ile mümkün olduğunca az bağlantı kurmalısınız.

NOT: bu işlem sonunca var_dump() ile $orderList değişkeninizi kontrol etmeniz gerekiyor. Çünkü sizin aldığınız json formatıyla bu yeni json formatı artık farklı. Ama her iki durumda da veritabanındaki aynı değerler artık elinizde.