Php sorgu hızlandırma
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;
}
}
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;