MySQL SELECT执行时间太长

时间:2016-01-18 02:07:19

标签: php mysql timeout

我目前在此SELECT过程中涉及5个表。并且这个查询可能会超过20,000条记录。

        $sql = "SELECT
                    ar_ledger.`company_code` AS ar_ledger_company_code,
                    ar_ledger.`project_code` AS ar_ledger_project_code,
                    ar_ledger.`phase_code` AS ar_ledger_phase_code,
                    ar_ledger.`unit_no` AS ar_ledger_unit_no,
                    ar_ledger.`sales_seq` AS ar_ledger_sales_seq,
                    ar_ledger.`debtor_acc` AS ar_ledger_debtor_acc,                                                
                    pr_tenancy.`name` AS pr_tenancy_name,
                    pr_tenancy.`terminate_date` AS pr_tenancy_terminate_date,
                    pr_tenancy.`status` AS pr_tenancy_status,
                    pr_tenancy_unit.`unit_no` AS pr_tenancy_unit_unit_no,
                    gn_trx_code.`bank_flag` AS bank_flag
               FROM
                    `ar_ledger` ar_ledger
                    INNER JOIN `pr_tenancy` pr_tenancy ON ar_ledger.`debtor_acc` = pr_tenancy.`debtor_acc` AND ar_ledger.`company_code` = pr_tenancy.`company_code` AND ar_ledger.`project_code` = pr_tenancy.`project_code` AND ar_ledger.`phase_code` = pr_tenancy.`phase_code`
                    INNER JOIN `pr_tenancy_unit` pr_tenancy_unit ON ar_ledger.`debtor_acc` = pr_tenancy_unit.`debtor_acc` AND
                        ar_ledger.`company_code` = pr_tenancy_unit.`company_code` AND ar_ledger.`project_code` = pr_tenancy_unit.`project_code` AND ar_ledger.`phase_code` = pr_tenancy_unit.`phase_code`
                    INNER JOIN pd_unit ON (pr_tenancy_unit.`company_code` = pd_unit.`company_code`)
                        AND (pr_tenancy_unit.`project_code` = pd_unit.`project_code`)
                        AND (pr_tenancy_unit.`phase_code` = pd_unit.`phase_code`)
                        AND (pr_tenancy_unit.`unit_no` = pd_unit.`unit_no`)
                    INNER JOIN gn_trx_code ON (ar_ledger.`company_code` = gn_trx_code.`company_code`)
                        AND (ar_ledger.`trx_code` = gn_trx_code.`trx_code`)
               WHERE
                     ar_ledger.`status`='A' AND ar_ledger.`ledger_type` = 'P' AND                          
                     CASE WHEN '$company'<>'' THEN ar_ledger.`company_code`='$company' ELSE ar_ledger.`company_code` IS NOT NULL END AND 
                     CASE WHEN '$project'<>'' THEN ar_ledger.`project_code`='$project' ELSE ar_ledger.`project_code` IS NOT NULL END AND 
                     CASE WHEN '$phase'<>'' THEN ar_ledger.`phase_code`='$phase' ELSE ar_ledger.`phase_code` IS NOT NULL END AND 
                     CASE WHEN '$property'<>'' THEN pd_unit.`property_code`='$property' ELSE pd_unit.`property_code` IS NOT NULL END AND 
                     CASE WHEN '$status'<>'' THEN pr_tenancy_unit.`status`='$status' ELSE pr_tenancy_unit.`status` IS NOT NULL END
               GROUP BY
               ar_ledger.`debtor_acc`
               ORDER BY
               ar_ledger.`debtor_acc`";

        $query = mysql_query($sql);
        $total = mysql_num_rows($query);

        $maindata = array();
        $count = 1;
        while($data = mysql_fetch_array($query)){  
            //echo '<script type="text/javascript">console.log("Processing '.$count.' rows...");</script>';

            $percent = intval($count/$total * 100)."%";

            // Javascript for updating the progress bar and information
            echo '<script language="javascript">
            document.getElementById("progress").innerHTML="<div style=\"width:'.$percent.';background-color:#ddd;\">&nbsp;</div>";
            document.getElementById("information").innerHTML="'.$percent.' processed.";
            </script>';  

            //terimaan awal
            $ksql1 = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        WHERE company_code='".$data['ar_ledger_company_code']."' 
                        AND project_code='".$data['ar_ledger_project_code']."' 
                        AND phase_code='".$data['ar_ledger_phase_code']."' 
                        AND mode='C' AND ledger_type='P' 
                        AND analysis_code='-' 
                        AND debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND status='A' 
                        AND YEAR(trx_date)=YEAR(DATE_ADD(str_to_date('$dateTo','%d-%m-%Y'),INTERVAL -1 YEAR))";
            $kamt1 = mysql_result(mysql_query($ksql1), 0);

            $ksql2 = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        WHERE company_code='".$data['ar_ledger_company_code']."' 
                        AND project_code='".$data['ar_ledger_project_code']."' 
                        AND phase_code='".$data['ar_ledger_phase_code']."' 
                        AND mode='D' AND ledger_type='P' 
                        AND analysis_code='-' 
                        AND debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND status='A' 
                        AND YEAR(trx_date)=YEAR(DATE_ADD(str_to_date('$dateTo','%d-%m-%Y'),INTERVAL -1 YEAR))";
            $kamt2 = mysql_result(mysql_query($ksql2), 0);                



            $dsql = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger
                        INNER JOIN gn_trx_code ON (ar_ledger.`company_code` = gn_trx_code.`company_code`)
                        AND (ar_ledger.`trx_code` = gn_trx_code.`trx_code`) 
                        WHERE ar_ledger.company_code='".$data['ar_ledger_company_code']."' 
                        AND ar_ledger.project_code='".$data['ar_ledger_project_code']."' 
                        AND ar_ledger.phase_code='".$data['ar_ledger_phase_code']."' 
                        AND ar_ledger.mode='C' AND ar_ledger.ledger_type='P' 
                        AND ar_ledger.trx_type='C' AND ar_ledger.analysis_code='-' 
                        AND gn_trx_code.bank_flag='N'
                        AND ar_ledger.debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND ar_ledger.status='A' 
                        AND ar_ledger.trx_date BETWEEN str_to_date('$dateForm','%d-%m-%Y') AND str_to_date('$dateTo','%d-%m-%Y')";
            $kontra_deposit = mysql_result(mysql_query($dsql), 0);


            $msql = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        WHERE company_code='".$data['ar_ledger_company_code']."' 
                        AND project_code='".$data['ar_ledger_project_code']."' 
                        AND phase_code='".$data['ar_ledger_phase_code']."' 
                        AND mode='D' AND ledger_type='P' 
                        AND debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND status='A' AND trx_type='D' 
                        AND analysis_code='-' 
                        AND trx_date BETWEEN str_to_date('$dateForm','%d-%m-%Y') AND str_to_date('$dateTo','%d-%m-%Y')";
            $tuntutan = mysql_result(mysql_query($msql), 0);


            $jsql = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        INNER JOIN gn_trx_code ON (ar_ledger.`company_code` = gn_trx_code.`company_code`)
                        AND (ar_ledger.`trx_code` = gn_trx_code.`trx_code`) 
                        WHERE ar_ledger.company_code='".$data['ar_ledger_company_code']."' 
                        AND ar_ledger.project_code='".$data['ar_ledger_project_code']."'
                        AND ar_ledger.phase_code='".$data['ar_ledger_phase_code']."' 
                        AND gn_trx_code.bank_flag='Y'
                        AND ar_ledger.mode='C' AND ar_ledger.ledger_type='P' 
                        AND ar_ledger.trx_type='C' AND ar_ledger.analysis_code='-' 
                        AND ar_ledger.debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND ar_ledger.status='A' 
                        AND ar_ledger.trx_date BETWEEN str_to_date('$dateForm','%d-%m-%Y') AND str_to_date('$dateTo','%d-%m-%Y')";
            $bayaran = mysql_result(mysql_query($jsql), 0);


            $rsql = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        WHERE company_code='".$data['ar_ledger_company_code']."' 
                        AND project_code='".$data['ar_ledger_project_code']."' 
                        AND phase_code='".$data['ar_ledger_phase_code']."' 
                        AND mode='D' AND ledger_type='P' 
                        AND trx_type='DN' AND analysis_code='-' 
                        AND debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND status='A' 
                        AND trx_date BETWEEN str_to_date('$dateForm','%d-%m-%Y') AND str_to_date('$dateTo','%d-%m-%Y')";
            $pelarasan_debit = mysql_result(mysql_query($rsql), 0);


            $psql = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        WHERE company_code='".$data['ar_ledger_company_code']."' 
                        AND project_code='".$data['ar_ledger_project_code']."' 
                        AND phase_code='".$data['ar_ledger_phase_code']."' 
                        AND mode='C' AND ledger_type='P' 
                        AND trx_type='CN' AND analysis_code='-' 
                        AND debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND status='A' 
                        AND trx_date BETWEEN str_to_date('$dateForm','%d-%m-%Y') AND str_to_date('$dateTo','%d-%m-%Y')";
            $pelarasan_kredit = mysql_result(mysql_query($psql), 0);


            $adsql = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger
                        INNER JOIN gn_trx_code ON (ar_ledger.`company_code` = gn_trx_code.`company_code`)
                        AND (ar_ledger.`trx_code` = gn_trx_code.`trx_code`)  
                        WHERE ar_ledger.company_code='".$data['ar_ledger_company_code']."' 
                        AND ar_ledger.project_code='".$data['ar_ledger_project_code']."' 
                        AND ar_ledger.phase_code='".$data['ar_ledger_phase_code']."' 
                        AND ar_ledger.mode='D' AND ar_ledger.ledger_type='P' 
                        AND ar_ledger.trx_type='DA' AND ar_ledger.analysis_code='-' 
                        AND gn_trx_code.bank_flag = 'N'
                        AND ar_ledger.debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND ar_ledger.status='A' 
                        AND ar_ledger.trx_date BETWEEN str_to_date('$dateForm','%d-%m-%Y') AND str_to_date('$dateTo','%d-%m-%Y')";
            $adjustment_debit = mysql_result(mysql_query($adsql), 0);


            $acsql = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger
                        INNER JOIN gn_trx_code ON (ar_ledger.`company_code` = gn_trx_code.`company_code`)
                        AND (ar_ledger.`trx_code` = gn_trx_code.`trx_code`) 
                        WHERE ar_ledger.company_code='".$data['ar_ledger_company_code']."' 
                        AND ar_ledger.project_code='".$data['ar_ledger_project_code']."' 
                        AND ar_ledger.phase_code='".$data['ar_ledger_phase_code']."' 
                        AND ar_ledger.mode='C' AND ar_ledger.ledger_type='P' 
                        AND ar_ledger.trx_type='CA' AND ar_ledger.analysis_code='-' 
                        AND gn_trx_code.bank_flag = 'N' 
                        AND ar_ledger.debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND ar_ledger.status='A' 
                        AND ar_ledger.trx_date BETWEEN str_to_date('$dateForm','%d-%m-%Y') AND str_to_date('$dateTo','%d-%m-%Y')";
            $adjustment_kredit = mysql_result(mysql_query($acsql), 0);


            $tsql1 = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        WHERE company_code='".$data['ar_ledger_company_code']."' 
                        AND project_code='".$data['ar_ledger_project_code']."' 
                        AND phase_code='".$data['ar_ledger_phase_code']."' 
                        AND mode='C' AND ledger_type='P' 
                        AND trx_type='C' AND analysis_code='-' 
                        AND debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND status='A' 
                        AND trx_date BETWEEN str_to_date(CONCAT('01-01-',YEAR(str_to_date('$dateTo','%d-%m-%Y'))),'%d-%m-%Y') AND str_to_date('$dateTo','%d-%m-%Y')";
            $tamt1 = mysql_result(mysql_query($tsql1), 0);

            $tsql2 = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        WHERE company_code='".$data['ar_ledger_company_code']."' 
                        AND project_code='".$data['ar_ledger_project_code']."' 
                        AND phase_code='".$data['ar_ledger_phase_code']."' 
                        AND mode='D' AND ledger_type='P' 
                        AND trx_type='D' AND analysis_code='-' 
                        AND debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND status='A' 
                        AND trx_date BETWEEN str_to_date(CONCAT('01-01-',YEAR(str_to_date('$dateTo','%d-%m-%Y'))),'%d-%m-%Y') AND str_to_date('$dateTo','%d-%m-%Y')";
            $tamt2 = mysql_result(mysql_query($tsql2), 0);
            //$terimaan_thsyr = $tamt1 - $tamt2;

            $bsql = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        WHERE company_code='".$data['ar_ledger_company_code']."' 
                        AND project_code='".$data['ar_ledger_project_code']."' 
                        AND phase_code='".$data['ar_ledger_phase_code']."' 
                        AND mode='D' 
                        AND ledger_type='P'                             
                        AND analysis_code='-' 
                        AND debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND status='A'                          
                        AND  YEAR(trx_date)<=YEAR(DATE_ADD(str_to_date('$dateTo','%d-%m-%Y'),INTERVAL -1 YEAR))";
            $bquery = mysql_query($bsql);
            $debit_amt = mysql_result($bquery, 0);

            $bsql2 = "SELECT COALESCE(SUM(trx_amt),0.00) FROM ar_ledger 
                        WHERE company_code='".$data['ar_ledger_company_code']."' 
                        AND project_code='".$data['ar_ledger_project_code']."' 
                        AND phase_code='".$data['ar_ledger_phase_code']."' 
                        AND mode='C' 
                        AND ledger_type='P'                             
                        AND analysis_code='-' 
                        AND debtor_acc = '".$data['ar_ledger_debtor_acc']."' 
                        AND status='A'                          
                        AND  YEAR(trx_date)<=YEAR(DATE_ADD(str_to_date('$dateTo','%d-%m-%Y'),INTERVAL -1 YEAR))";
            $bquery2 = mysql_query($bsql2);
            $credit_amt = mysql_result($bquery2, 0);

            $bal_awal = $debit_amt - $credit_amt;
            if($bal_awal>0){
                $baki_awal = $bal_awal;
                $terimaan_awal = 0;
            }else{
                $baki_awal = 0;
                $terimaan_awal = abs($bal_awal);
            }

            $balance = ($baki_awal<0?0:$baki_awal)-($terimaan_awal<0?0:$terimaan_awal)+($tuntutan<0?0:$tuntutan)-($bayaran<0?0:$bayaran)-($kontra_deposit<0?0:$kontra_deposit)+($pelarasan_debit<0?0:$pelarasan_debit)-($pelarasan_kredit<0?0:$pelarasan_kredit)+($adjustment_debit<0?0:$adjustment_debit)-($adjustment_kredit<0?0:$adjustment_kredit);

            if($balance > 0){
                $tunggakan_eachline = $balance;
                $terimaan_thsyr = 0;
            }else{
                $tunggakan_eachline = 0;
                $terimaan_thsyr = abs($balance);
            }

            if((($data['pr_tenancy_status']=="T") && ($baki_awal>0 || $terimaan_awal>0 || $tunggakan_eachline>0 || $terimaan_thsyr>0))||($data['pr_tenancy_status']!="T")||($data['pr_tenancy_status']=="T" && $data['pr_tenancy_terminate_date']>=ConvertToMySQLDate($dateForm))){
                $subdata = array();
                $subdata['account_name'] = $data['pr_tenancy_name']."-".$data['ar_ledger_debtor_acc']."-".$data['pr_tenancy_unit_unit_no'];
                $subdata['baki_awal'] = $baki_awal;
                $subdata['terimaan_awal'] = $terimaan_awal;
                $subdata['kontra_deposit'] = $kontra_deposit;
                $subdata['tuntutan'] = $tuntutan;
                $subdata['bayaran'] = $bayaran;
                $subdata['pelarasan_debit'] = $pelarasan_debit;
                $subdata['pelarasan_kredit'] = $pelarasan_kredit;
                                $subdata['adjustment_debit'] = $adjustment_debit;
                $subdata['adjustment_kredit'] = $adjustment_kredit;
                $subdata['terimaan_thsyr'] = $terimaan_thsyr;
                $subdata['tunggakan_eachline'] = $tunggakan_eachline;
                $subdata['tenancy_status'] = $data['pr_tenancy_status'];
                $subdata['terminate_date'] = $data['pr_tenancy_terminate_date'];
                $maindata[] = $subdata;
            }
            $count ++;
            // This is for the buffer achieve the minimum size in order to flush data
            echo str_repeat(' ',1024*64);

            // Send output to browser immediately
            flush();

            // Sleep one second so we can see the delay
            sleep(1);     
        }

即使在等待30分钟后,此查询也不会给出任何响应。有一个进度条会在每个循环中更新,但事实是,当我运行 mysql> show full processlist 时,当进度条缓冲时,此查询的mysql状态为{{ 1}}。但是,在显示进度条之前有mysql活动。这些代码有什么问题吗?谢谢

EXPLAIN Results

1 个答案:

答案 0 :(得分:0)

睡眠超过5 1/2小时

&#34;这个查询可能会超过20,000条记录。&#34;

第一个查询实际返回的行数是多少? (您可以从其他环境测试查询。您可以通过将查询引用为内联视图来获取查询的行数... SELECT COUNT(1) FROM ( <original query here> ) q

如果该查询返回20,000多行(正如您的问题似乎表明的那样),则看起来fetch循环底部的 sleep(1) 语句将被执行20,000倍。如果我正在做正确的数学计算,那就是超过333分钟,这超过了5个半小时的睡眠时间。