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;
}
}
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.