대용량 MySQL 데이터베이스에서 데이터를 가져 오는 데 문제가 있습니다.대용량 MySQL 데이터베이스에서 데이터를 가져 오기 위해 SQL 쿼리 최적화
아래 코드를 사용하면 테스트 서버 인 10K 환자 및 5K 약속 목록을 얻는 것이 좋습니다.
그러나 라이브 서버의 경우 환자 수가 100K 이상이고 약속 수는 300K 이상이며 잠시 후 코드를 실행하면 500 오류가 발생합니다.
patient_treatment_status가 1 또는 3 인 환자 목록이 필요하며 마지막 약속으로부터 한 달 후에 약속이 없습니다. (아래 코드는 소량의 환자와 약속을 위해 작동합니다.)
foreach 루프에서 두 번째 데이터베이스 쿼리가 필요하지 않도록 첫 번째 데이터베이스 쿼리를 최적화하려면 어떻게해야합니까?
<?php
ini_set('memory_limit', '-1');
ini_set('max_execution_time', 0);
require_once('Db.class.php');
$patients = $db->query("
SELECT
p.id, p.first_name, p.last_name, p.phone, p.mobile,
LatestApp.lastAppDate
FROM
patients p
LEFT JOIN (SELECT patient_id, MAX(start_date) AS lastAppDate FROM appointments WHERE appointment_status = 4) LatestApp ON p.id = LatestApp.patient_id
WHERE
p.patient_treatment_status = 1 OR p.patient_treatment_status = 3
ORDER BY
p.id
");
foreach ($patients as $row) {
$one_month_after_the_last_appointment = date('Y-m-d', strtotime($row['lastAppDate'] . " +1 month"));
$appointment_check = $db->single("SELECT COUNT(id) FROM appointments WHERE patient_id = :pid AND appointment_status = :a0 AND (start_date >= :a1 AND start_date <= :a2)", array("pid"=>"{$row['id']}","a0"=>"1","a1"=>"{$row['lastAppDate']}","a2"=>"$one_month_after_the_last_appointment"));
if($appointment_check == 0){
echo $patient_id = $row['id'].' - '.$row['lastAppDate'].' - '.$one_month_after_the_last_appointment. '<br>';
}
}
?>
나라면, 지금은 모든 php를 제거하고 대신 SQL에 집중할 것입니다. 동의하면 https://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple을 참조하십시오. -sql-query – Strawberry
두 개의 쿼리, 특히 루프의 쿼리를 실행하면 안됩니다. –
속도 문제는 하위 쿼리와 LEFT JOIN에 상대적이라고 생각합니다. 나는 당신이 쿼리를 빠르게하고, 하위 쿼리를 제거하고, 다른 테이블을 조인하고, 약속 ID (있는 경우)로 그룹을 사용하고, MAX를 사용하여 선택하여 최신 약속을 얻는 INNER JOIN을 사용하는 것이 좋습니다. . – Lucarnosky